").appendTo(DX.overlayTargetContainer()).dxToast(options).dxToast("instance").show()
};
$.extend(ui, {
notify: notify,
dialog: {
custom: dialog,
alert: alert,
confirm: confirm,
FakeDialogComponent: FakeDialogComponent
}
})
})(jQuery, DevExpress);
/*! Module core, file ui.dataHelper.js */
(function($, DX, undefined) {
var data = DX.data;
var DATA_SOURCE_OPTIONS_METHOD = "_dataSourceOptions",
DATA_SOURCE_CHANGED_METHOD = "_handleDataSourceChanged",
DATA_SOURCE_LOAD_ERROR_METHOD = "_handleDataSourceLoadError",
DATA_SOURCE_LOADING_CHANGED_METHOD = "_handleDataSourceLoadingChanged";
DX.ui.DataHelperMixin = {
ctor: function() {
this.disposing.add(function() {
this._disposeDataSource()
})
},
_refreshDataSource: function() {
this._initDataSource();
this._loadDataSource()
},
_initDataSource: function() {
var dataSourceOptions = this.option("dataSource"),
widgetDataSourceOptions,
dataSourceType;
this._disposeDataSource();
if (dataSourceOptions) {
if (dataSourceOptions instanceof data.DataSource) {
this._isSharedDataSource = true;
this._dataSource = dataSourceOptions
}
else {
widgetDataSourceOptions = DATA_SOURCE_OPTIONS_METHOD in this ? this[DATA_SOURCE_OPTIONS_METHOD]() : {};
dataSourceType = this._dataSourceType ? this._dataSourceType() : data.DataSource;
this._dataSource = new dataSourceType($.extend(true, {}, widgetDataSourceOptions, data.utils.normalizeDataSourceOptions(dataSourceOptions)))
}
this._addDataSourceHandlers()
}
},
_addDataSourceHandlers: function() {
if (DATA_SOURCE_CHANGED_METHOD in this)
this._addDataSourceChangeHandler();
if (DATA_SOURCE_LOAD_ERROR_METHOD in this)
this._addDataSourceLoadErrorHandler();
if (DATA_SOURCE_LOADING_CHANGED_METHOD in this)
this._addDataSourceLoadingChangedHandler()
},
_addDataSourceChangeHandler: function() {
var that = this,
dataSource = this._dataSource;
this._dataSourceChangedHandler = function() {
that[DATA_SOURCE_CHANGED_METHOD](dataSource.items())
};
dataSource.changed.add(this._dataSourceChangedHandler)
},
_addDataSourceLoadErrorHandler: function() {
this._dataSourceLoadErrorHandler = $.proxy(this[DATA_SOURCE_LOAD_ERROR_METHOD], this);
this._dataSource.loadError.add(this._dataSourceLoadErrorHandler)
},
_addDataSourceLoadingChangedHandler: function() {
this._dataSourceLoadingChangedHandler = $.proxy(this[DATA_SOURCE_LOADING_CHANGED_METHOD], this);
this._dataSource.loadingChanged.add(this._dataSourceLoadingChangedHandler)
},
_loadDataSource: function() {
if (this._dataSource) {
var dataSource = this._dataSource;
if (dataSource.isLoaded())
this._dataSourceChangedHandler();
else
dataSource.load()
}
},
_loadSingle: function(key, value) {
key = key === "this" ? this._dataSource.key() || "this" : key;
return this._dataSource.loadSingle(key, value)
},
_disposeDataSource: function() {
if (this._dataSource) {
if (this._isSharedDataSource) {
delete this._isSharedDataSource;
this._dataSource.changed.remove(this._dataSourceChangedHandler);
this._dataSource.loadError.remove(this._dataSourceLoadErrorHandler);
this._dataSource.loadingChanged.remove(this._dataSourceLoadingChangedHandler)
}
else
this._dataSource.dispose();
delete this._dataSource;
delete this._dataSourceChangedHandler;
delete this._dataSourceLoadErrorHandler;
delete this._dataSourceLoadingChangedHandler
}
}
}
})(jQuery, DevExpress);
/*! Module core, file ui.events.mspointer.js */
(function($, DX, undefined) {
var POINTER_TYPE_MAP = {
2: "touch",
3: "pen",
4: "mouse"
};
var pointerEventHook = {
filter: function(event, originalEvent) {
var pointerType = originalEvent.pointerType;
if ($.isNumeric(pointerType))
event.pointerType = POINTER_TYPE_MAP[pointerType];
return event
},
props: $.event.mouseHooks.props.concat(["pointerId", "originalTarget", "namespace", "width", "height", "pressure", "result", "tiltX", "charCode", "tiltY", "detail", "isPrimary", "prevValue"])
};
$.each(["MSPointerDown", "MSPointerMove", "MSPointerUp", "MSPointerCancel", "MSPointerOver", "MSPointerOut", "MSPointerEnter", "MSPointerLeave", "pointerdown", "pointermove", "pointerup", "pointercancel", "pointerover", "pointerout", "pointerenter", "pointerleave"], function() {
$.event.fixHooks[this] = pointerEventHook
})
})(jQuery, DevExpress);
/*! Module core, file ui.events.touch.js */
(function($, DX, undefined) {
var touchEventHook = {
filter: function(event, originalEvent) {
if (originalEvent.changedTouches.length)
$.each(["pageX", "pageY", "screenX", "screenY", "clientX", "clientY"], function() {
event[this] = originalEvent.changedTouches[0][this]
});
return event
},
props: $.event.mouseHooks.props.concat(["touches", "changedTouches", "targetTouches", "detail", "result", "namespace", "originalTarget", "charCode", "prevValue"])
};
$.each(["touchstart", "touchmove", "touchend", "touchcancel"], function() {
$.event.fixHooks[this] = touchEventHook
})
})(jQuery, DevExpress);
/*! Module core, file ui.events.pointer.js */
(function($, DX, undefined) {
var ui = DX.ui,
support = DX.support,
device = $.proxy(DX.devices.real, DX.devices),
events = ui.events;
var POINTER_EVENTS_NAMESPACE = "dxPointerEvents",
MouseStrategyEventMap = {
dxpointerdown: "mousedown",
dxpointermove: "mousemove",
dxpointerup: "mouseup",
dxpointercancel: ""
},
TouchStrategyEventMap = {
dxpointerdown: "touchstart",
dxpointermove: "touchmove",
dxpointerup: "touchend",
dxpointercancel: "touchcancel"
},
PointerStrategyEventMap = {
dxpointerdown: "pointerdown",
dxpointermove: "pointermove",
dxpointerup: "pointerup",
dxpointercancel: "pointercancel"
},
MouseAndTouchStrategyEventMap = {
dxpointerdown: "touchstart mousedown",
dxpointermove: "touchmove mousemove",
dxpointerup: "touchend mouseup",
dxpointercancel: "touchcancel"
};
var eventMap = function() {
if (support.touch && !(device().tablet || device().phone))
return MouseAndTouchStrategyEventMap;
if (support.pointer)
return MouseStrategyEventMap;
if (support.touch)
return TouchStrategyEventMap;
return MouseStrategyEventMap
}();
var skipTouchWithSameIdentifier = function(pointerEvent) {
return device().platform === "ios" && (pointerEvent === "dxpointerdown" || pointerEvent === "dxpointerup")
};
var SingleEventStrategy = DX.Class.inherit({
ctor: function(eventName, originalEvents) {
this._eventName = eventName;
this._eventNamespace = [POINTER_EVENTS_NAMESPACE, ".", this._eventName].join("");
this._originalEvents = originalEvents;
this._pointerId = 0;
this._handlerCount = 0
},
_handler: function(e) {
if (this._eventName === "dxpointerdown")
$(e.target).data("dxGestureEvent", null);
if (events.isTouchEvent(e) && skipTouchWithSameIdentifier(this._eventName)) {
var touch = e.changedTouches[0];
if (this._pointerId === touch.identifier && this._pointerId !== 0)
return;
this._pointerId = touch.identifier
}
return events.fireEvent({
type: this._eventName,
pointerType: events.eventSource(e),
originalEvent: e
})
},
setup: function() {
if (this._handlerCount > 0)
return;
$(document).on(events.addNamespace(this._originalEvents, this._eventNamespace), $.proxy(this._handler, this))
},
add: function() {
this._handlerCount++
},
remove: function() {
this._handlerCount--
},
teardown: function() {
if (this._handlerCount)
return;
$(document).off("." + this._eventNamespace)
},
dispose: function() {
$(document).off("." + this._eventNamespace)
}
});
var MultiEventStrategy = SingleEventStrategy.inherit({
EVENT_LOCK_TIMEOUT: 100,
_handler: function(e) {
if (events.isTouchEvent(e))
this._skipNextEvents = true;
if (events.isMouseEvent(e) && this._mouseLocked)
return;
if (events.isMouseEvent(e) && this._skipNextEvents) {
this._skipNextEvents = false;
this._mouseLocked = true;
clearTimeout(this._unlockMouseTimer);
this._unlockMouseTimer = setTimeout($.proxy(function() {
this._mouseLocked = false
}, this), this.EVENT_LOCK_TIMEOUT);
return
}
return this.callBase(e)
},
dispose: function() {
this.callBase();
this._skipNextEvents = false;
this._mouseLocked = false;
clearTimeout(this._unlockMouseTimer)
}
});
var getStrategy = function() {
return eventMap === MouseAndTouchStrategyEventMap ? MultiEventStrategy : SingleEventStrategy
};
$.each(eventMap, function(pointerEvent, originalEvents) {
var Strategy = getStrategy();
events.registerEvent(pointerEvent, new Strategy(pointerEvent, originalEvents))
});
DX.ui.events.__internals = DX.ui.events.__internals || {};
$.extend(DX.ui.events.__internals, {
SingleEventStrategy: SingleEventStrategy,
MultiEventStrategy: MultiEventStrategy,
MouseStrategyEventMap: MouseStrategyEventMap,
TouchStrategyEventMap: TouchStrategyEventMap,
PointerStrategyEventMap: PointerStrategyEventMap,
MouseAndTouchStrategyEventMap: MouseAndTouchStrategyEventMap,
eventMap: eventMap
})
})(jQuery, DevExpress);
/*! Module core, file ui.events.click.js */
(function($, DX, wnd, undefined) {
var ua = navigator.userAgent,
screen = wnd.screen,
ui = DX.ui,
utils = DX.utils,
events = ui.events,
support = DX.support,
device = $.proxy(DX.devices.real, DX.devices),
EVENTS_NAME_SPACE = "dxSpecialEvents",
CLICK_NAME_SPACE = "dxClick" + EVENTS_NAME_SPACE,
CLICK_EVENT_NAME = "dxclick",
SCROLLABLE_PARENT_DATA_KEY = "dxClickScrollableParent",
SCROLLABLE_PARENT_SCROLL_OFFSET_DATA_KEY = "dxClickScrollableParentOffset",
preferNativeClick = function() {
var iPhone4SAndElder = device().deviceType === "phone" && screen.height <= 480,
iPad2AndElder = device().deviceType === "tablet" && wnd.devicePixelRatio < 2,
IOS7AndNewer = device().platform === "ios" && device().version[0] > 6;
return IOS7AndNewer && (iPhone4SAndElder || iPad2AndElder)
}(),
useNativeClick = function() {
if (!support.touch)
return true;
var chromeInfo = ua.match(/Chrome\/([0-9]+)/) || [],
chrome = !!chromeInfo[0],
chromeVersion = ~~chromeInfo[1],
android = device().platform === "android";
if (chrome)
if (android) {
if ($("meta[name=viewport][content*='width=device-width']").length)
return false;
if (chromeVersion > 31 && wnd.innerWidth <= screen.width)
return true;
if ($("meta[name=viewport][content*='user-scalable=no']").length)
return true
}
else
return true;
return false
}();
var SimulatedStrategy = DX.Class.inherit({
TOUCH_BOUNDARY: 10,
ctor: function() {
this._startX = 0;
this._startY = 0;
this._handlerCount = 0;
this._target = null
},
_touchWasMoved: function(e) {
var boundary = this.TOUCH_BOUNDARY;
return Math.abs(e.pageX - this._startX) > boundary || Math.abs(e.pageY - this._startY) > boundary
},
_getClosestScrollable: function($element) {
var $scrollParent = $();
if ($element.data(SCROLLABLE_PARENT_DATA_KEY))
$scrollParent = $element.data(SCROLLABLE_PARENT_DATA_KEY);
else {
var $current = $element;
while ($current.length) {
if ($current[0].scrollHeight - $current[0].offsetHeight > 1) {
$scrollParent = $current;
$element.data(SCROLLABLE_PARENT_DATA_KEY, $scrollParent);
break
}
$current = $current.parent()
}
}
return $scrollParent
},
_saveClosestScrollableOffset: function($element) {
var $scrollable = this._getClosestScrollable($element);
if ($scrollable.length)
$element.data(SCROLLABLE_PARENT_SCROLL_OFFSET_DATA_KEY, $scrollable.scrollTop())
},
_closestScrollableWasMoved: function($element) {
var $scrollable = $element.data(SCROLLABLE_PARENT_DATA_KEY);
return $scrollable && $scrollable.scrollTop() !== $element.data(SCROLLABLE_PARENT_SCROLL_OFFSET_DATA_KEY)
},
_hasClosestScrollable: function($element) {
var $scrollable = this._getClosestScrollable($element);
if (!$scrollable.length)
return false;
if ($scrollable.is("body"))
return false;
if ($scrollable === window)
return false;
if ($scrollable.css("overflow") === "hidden")
return false;
return true
},
_handleStart: function(e) {
this._reset();
if (events.isMouseEvent(e) && e.which !== 1)
return;
this._saveClosestScrollableOffset($(e.target));
this._target = e.target;
this._startX = e.pageX;
this._startY = e.pageY
},
_handleEnd: function(e) {
var $target = $(e.target);
if (!$target.is(this._target) || this._touchWasMoved(e))
return;
if (this._nativeClickShouldBeUsed($target) || this._closestScrollableWasMoved($target))
return;
var targetIsInput = $target.is("input, textarea");
if (!targetIsInput && !e.dxPreventBlur)
utils.resetActiveElement();
this._fireClickEvent(e)
},
_handleCancel: function(e) {
this._reset()
},
_reset: function() {
this._target = null
},
_handleClick: function(e) {
var $target = $(e.target);
if ($target.is(this._target)) {
if (this._nativeClickShouldBeUsed($target))
this._fireClickEvent(e)
}
else if ($target.is("input, textarea"))
utils.resetActiveElement()
},
_nativeClickShouldBeUsed: function($target) {
return preferNativeClick && this._hasClosestScrollable($target)
},
_fireClickEvent: function(e) {
if (events.handleGestureEvent(e, CLICK_EVENT_NAME))
events.fireEvent({
type: CLICK_EVENT_NAME,
originalEvent: e
})
},
_makeElementClickable: function($element) {
if (!$element.attr("onclick"))
$element.attr("onclick", "void(0)")
},
setup: function(element) {
var $element = $(element);
this._makeElementClickable($element);
if (this._handlerCount > 0)
return;
var $doc = $(document).on(events.addNamespace("dxpointerdown", CLICK_NAME_SPACE), $.proxy(this._handleStart, this)).on(events.addNamespace("dxpointerup", CLICK_NAME_SPACE), $.proxy(this._handleEnd, this)).on(events.addNamespace("dxpointercancel", CLICK_NAME_SPACE), $.proxy(this._handleCancel, this)).on(events.addNamespace("click", CLICK_NAME_SPACE), $.proxy(this._handleClick, this))
},
add: function() {
this._handlerCount++
},
remove: function() {
this._handlerCount--
},
teardown: function(element) {
if (this._handlerCount)
return;
$(element).off("." + CLICK_NAME_SPACE);
this.dispose()
},
dispose: function() {
$(document).off("." + CLICK_NAME_SPACE)
}
});
var NativeStrategy = DX.Class.inherit({
bindType: "click",
delegateType: "click",
handle: function(element, event) {
event.type = "dxclick";
if (events.handleGestureEvent(event, CLICK_EVENT_NAME))
return event.handleObj.handler.call(element, event)
}
});
events.registerEvent(CLICK_EVENT_NAME, new(useNativeClick ? NativeStrategy : SimulatedStrategy));
DX.ui.events.__internals = DX.ui.events.__internals || {};
$.extend(DX.ui.events.__internals, {
NativeClickStrategy: NativeStrategy,
SimulatedClickStrategy: SimulatedStrategy,
preferNativeClickAccessor: function(value) {
if (!arguments.length)
return preferNativeClick;
preferNativeClick = value
}
})
})(jQuery, DevExpress, window);
/*! Module core, file ui.events.hold.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
jqSpecialEvent = $.event.special,
EVENTS_NAME_SPACE = "dxSpecialEvents",
HOLD_NAME_SPACE = "dxHold",
HOLD_EVENT_NAME = "dxhold",
HOLD_TIMER_DATA_KEY = EVENTS_NAME_SPACE + "HoldTimer";
var Hold = DX.Class.inherit({
HOLD_TIMEOUT: 750,
TOUCH_BOUNDARY: 5,
_startX: 0,
_startY: 0,
_touchWasMoved: function(e) {
var boundary = this.TOUCH_BOUNDARY;
return Math.abs(e.pageX - this._startX) > boundary || Math.abs(e.pageY - this._startY) > boundary
},
setup: function(element, data) {
var $target,
holdInited = false;
var handleStart = function(e) {
if (holdInited)
return;
$target = $(e.target);
holdInited = true;
if ($target.data(HOLD_TIMER_DATA_KEY))
return;
this._startX = e.pageX;
this._startY = e.pageY;
var holdTimeout = data && "timeout" in data ? data.timeout : this.HOLD_TIMEOUT;
var holdTimer = setTimeout(function() {
$target.removeData(HOLD_TIMER_DATA_KEY);
if (events.handleGestureEvent(e, HOLD_EVENT_NAME))
events.fireEvent({
type: HOLD_EVENT_NAME,
originalEvent: e
})
}, holdTimeout);
$target.data(HOLD_TIMER_DATA_KEY, holdTimer)
};
var handleMove = function(e) {
if (!this._touchWasMoved(e))
return;
handleEnd()
};
var handleEnd = function() {
if ($target) {
clearTimeout($target.data(HOLD_TIMER_DATA_KEY));
$target.removeData(HOLD_TIMER_DATA_KEY);
$target = null;
holdInited = false
}
};
$(element).on(events.addNamespace("dxpointerdown", HOLD_NAME_SPACE), $.proxy(handleStart, this)).on(events.addNamespace("dxpointermove", HOLD_NAME_SPACE), $.proxy(handleMove, this)).on(events.addNamespace("dxpointerup", HOLD_NAME_SPACE), $.proxy(handleEnd, this))
},
teardown: function(element) {
element = $(element);
clearTimeout(element.data(HOLD_TIMER_DATA_KEY));
element.removeData(HOLD_TIMER_DATA_KEY).off("." + HOLD_NAME_SPACE)
}
});
events.registerEvent(HOLD_EVENT_NAME, new Hold)
})(jQuery, DevExpress);
/*! Module core, file ui.events.hover.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var HOVER_EVENTS_NAMESPACE = "dxSpecialEvents",
HOVER_START = "dxhoverstart",
HOVER_END = "dxhoverend",
MOUSE_ENTER = "mouseenter",
MOUSE_LEAVE = "mouseleave",
TOUCH_START = "dxpointerdown";
var HoverStart = DX.Class.inherit({
ctor: function() {
this._wasTouch = false;
this._selector = undefined
},
setup: function(element, data) {
var $element = $(element);
this._selector = data ? data.selector : undefined;
if (!!$element.data("dxHoverStart"))
return;
$element.data("dxHoverStart", true).on(events.addNamespace(MOUSE_ENTER, HOVER_EVENTS_NAMESPACE), this._selector, $.proxy(this._handleEnter, this)).on(events.addNamespace(TOUCH_START, HOVER_EVENTS_NAMESPACE), $.proxy(this._handleTouchStart, this))
},
_handleEnter: function(e) {
if (!this._wasTouch)
events.fireEvent({
type: HOVER_START,
originalEvent: e
})
},
_handleTouchStart: function(e) {
this._wasTouch = events.isTouchEvent(e)
},
teardown: function(element) {
$(element).data("dxHoverStart", false).off(events.addNamespace(MOUSE_ENTER, HOVER_EVENTS_NAMESPACE), this._selector).off(events.addNamespace(TOUCH_START, HOVER_EVENTS_NAMESPACE))
}
});
var HoverEnd = DX.Class.inherit({
ctor: function() {
this._wasTouch = false;
this._selector = undefined
},
setup: function(element, data) {
var $element = $(element);
this._selector = data ? data.selector : undefined;
if (!!$element.data("dxHoverEnd"))
return;
$element.data("dxHoverEnd", true).on(events.addNamespace(MOUSE_LEAVE, HOVER_EVENTS_NAMESPACE), this._selector, $.proxy(this._handleLeave, this)).on(events.addNamespace(TOUCH_START, HOVER_EVENTS_NAMESPACE), $.proxy(this._handleTouchStart, this))
},
_handleLeave: function(e) {
if (!this._wasTouch)
events.fireEvent({
type: HOVER_END,
originalEvent: e
})
},
_handleTouchStart: function(e) {
this._wasTouch = events.isTouchEvent(e)
},
teardown: function(element) {
$(element).data("dxHoverEnd", false).off(events.addNamespace(MOUSE_LEAVE, HOVER_EVENTS_NAMESPACE), this._selector).off(events.addNamespace(TOUCH_START, HOVER_EVENTS_NAMESPACE))
}
});
events.registerEvent(HOVER_START, new HoverStart);
events.registerEvent(HOVER_END, new HoverEnd)
})(jQuery, DevExpress);
/*! Module core, file ui.events.wheel.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var EVENT_NAME = "dxmousewheel",
EVENT_NAMESPACE = "dxWheel";
var WHEEL_DISTANCE = 10;
$.event.fixHooks["wheel"] = $.event.mouseHooks;
var wheelEvent = document.onmousewheel !== undefined ? "mousewheel" : "wheel";
var wheel = {
setup: function(element, data) {
var $element = $(element);
$element.on(events.addNamespace(wheelEvent, EVENT_NAMESPACE), $.proxy(wheel._handleWheel, wheel))
},
teardown: function(element) {
var $element = $(element);
$element.off("." + EVENT_NAMESPACE)
},
_handleWheel: function(e) {
$(e.target).data("dxGestureEvent", null);
var delta = this._getWheelDelta(e.originalEvent);
events.fireEvent({
type: EVENT_NAME,
originalEvent: e,
delta: delta
});
e.stopPropagation()
},
_getWheelDelta: function(event) {
return event.wheelDelta / 60 || -event.deltaY
}
};
events.registerEvent(EVENT_NAME, wheel)
})(jQuery, DevExpress);
/*! Module core, file ui.gestureEmitter.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var GestureEmitter = DX.Class.inherit({
ctor: function(element) {
this._$element = $(element);
this._cancelCallback = $.Callbacks()
},
getElement: function() {
return this._$element
},
getDirection: function() {
return this.direction
},
validate: function(e) {
return e.type !== "dxmousewheel"
},
configurate: function(data) {
$.extend(this, data)
},
addCancelCallback: function(callback) {
this._cancelCallback.add(callback)
},
removeCancelCallback: function() {
this._cancelCallback.empty()
},
init: $.noop,
start: $.noop,
move: $.noop,
end: $.noop,
cancel: $.noop,
wheel: $.noop,
_fireEvent: function(eventName, event, params) {
var eventData = {
type: eventName,
originalEvent: event,
target: this.getElement().get(0)
};
event = events.fireEvent($.extend(eventData, params));
if (event.cancel)
this._cancel(event);
return event
},
_cancel: function(e) {
this._cancelCallback.fire()
}
});
var gestureEmitters = [];
$.extend(ui, {
GestureEmitter: GestureEmitter,
gestureEmitters: gestureEmitters
})
})(jQuery, DevExpress);
/*! Module core, file ui.scrollEmitter.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var SCROLL_INIT_EVENT = "dxscrollinit",
SCROLL_START_EVENT = "dxscrollstart",
SCROLL_MOVE_EVENT = "dxscroll",
SCROLL_END_EVENT = "dxscrollend",
SCROLL_STOP_EVENT = "dxscrollstop",
SCROLL_CANCEL_EVENT = "dxscrollcancel",
SCROLL_WHEEL_EVENT = "dxscrollwheel",
INERTIA_TIMEOUT = 100,
VELOCITY_CALC_TIMEOUT = 200,
FRAME_DURATION = Math.round(1000 / 60);
var ScrollEmitter = ui.GestureEmitter.inherit({
ctor: function(element) {
this.callBase(element);
this.direction = "vertical"
},
init: function(e) {
this._savedEventData = this._prevEventData = events.eventData(e);
this._fireEvent(SCROLL_INIT_EVENT, e)
},
start: function(e) {
this._fireEvent(SCROLL_START_EVENT, e, {delta: events.eventDelta(this._prevEventData, events.eventData(e))})
},
move: function(e) {
var currentEventData = events.eventData(e);
this._fireEvent(SCROLL_MOVE_EVENT, e, {delta: events.eventDelta(this._prevEventData, currentEventData)});
var eventDelta = events.eventDelta(this._savedEventData, currentEventData);
if (eventDelta.time > VELOCITY_CALC_TIMEOUT)
this._savedEventData = this._prevEventData;
this._prevEventData = currentEventData
},
end: function(e) {
var endEventDelta = events.eventDelta(this._prevEventData, events.eventData(e));
var velocity = {
x: 0,
y: 0
};
if (endEventDelta.time < INERTIA_TIMEOUT) {
var deltaEventData = events.eventDelta(this._savedEventData, this._prevEventData);
velocity = {
x: deltaEventData.x * FRAME_DURATION / deltaEventData.time,
y: deltaEventData.y * FRAME_DURATION / deltaEventData.time
}
}
this._fireEvent(SCROLL_END_EVENT, e, {velocity: velocity})
},
stop: function(e) {
this._fireEvent(SCROLL_STOP_EVENT, e)
},
cancel: function(e) {
this._fireEvent(SCROLL_CANCEL_EVENT, e)
},
wheel: function(e) {
this._fireEvent(SCROLL_WHEEL_EVENT, e, {delta: e.delta})
}
});
ui.gestureEmitters.push({
emitter: ScrollEmitter,
events: [SCROLL_INIT_EVENT, SCROLL_START_EVENT, SCROLL_MOVE_EVENT, SCROLL_END_EVENT, SCROLL_STOP_EVENT, SCROLL_CANCEL_EVENT, SCROLL_WHEEL_EVENT]
})
})(jQuery, DevExpress);
/*! Module core, file ui.swipeEmitter.js */
(function($, DX, undefined) {
var ui = DX.ui,
utils = DX.utils,
events = ui.events,
SWIPE_START_EVENT = "dxswipestart",
SWIPE_EVENT = "dxswipe",
SWIPE_END_EVENT = "dxswipeend";
var HorizontalStrategy = {
defaultItemSizeFunc: function() {
return this.getElement().width()
},
getBounds: function() {
return [this._maxLeftOffset, this._maxRightOffset]
},
calcOffsetRatio: function(e) {
var endEventData = events.eventData(e);
return (endEventData.x - (this._startEventData && this._startEventData.x || 0)) / this._itemSizeFunc().call(this, e)
},
isFastSwipe: function(e) {
var endEventData = events.eventData(e);
return this.FAST_SWIPE_SPEED_LIMIT * Math.abs(endEventData.x - this._tickData.x) >= endEventData.time - this._tickData.time
}
};
var VerticalStrategy = {
defaultItemSizeFunc: function() {
return this.getElement().height()
},
getBounds: function() {
return [this._maxTopOffset, this._maxBottomOffset]
},
calcOffsetRatio: function(e) {
var endEventData = events.eventData(e);
return (endEventData.y - (this._startEventData && this._startEventData.y || 0)) / this._itemSizeFunc().call(this, e)
},
isFastSwipe: function(e) {
var endEventData = events.eventData(e);
return this.FAST_SWIPE_SPEED_LIMIT * Math.abs(endEventData.y - this._tickData.y) >= endEventData.time - this._tickData.time
}
};
var STRATEGIES = {
horizontal: HorizontalStrategy,
vertical: VerticalStrategy
};
var SwipeEmitter = ui.GestureEmitter.inherit({
TICK_INTERVAL: 300,
FAST_SWIPE_SPEED_LIMIT: 5,
ctor: function(element) {
this.callBase(element);
this.direction = "horizontal";
this.elastic = true
},
_getStrategy: function() {
return STRATEGIES[this.direction]
},
_defaultItemSizeFunc: function() {
return this._getStrategy().defaultItemSizeFunc.call(this)
},
_itemSizeFunc: function() {
return this.itemSizeFunc || this._defaultItemSizeFunc
},
init: function(e) {
this._startEventData = events.eventData(e);
this._tickData = {time: 0}
},
start: function(e) {
e = this._fireEvent(SWIPE_START_EVENT, e);
if (!e.cancel) {
this._maxLeftOffset = e.maxLeftOffset;
this._maxRightOffset = e.maxRightOffset;
this._maxTopOffset = e.maxTopOffset;
this._maxBottomOffset = e.maxBottomOffset
}
},
move: function(e) {
var strategy = this._getStrategy(),
moveEventData = events.eventData(e),
offset = strategy.calcOffsetRatio.call(this, e);
offset = this._fitOffset(offset, this.elastic);
if (moveEventData.time - this._tickData.time > this.TICK_INTERVAL)
this._tickData = moveEventData;
this._fireEvent(SWIPE_EVENT, e, {offset: offset});
e.preventDefault()
},
end: function(e) {
var strategy = this._getStrategy(),
offsetRatio = strategy.calcOffsetRatio.call(this, e),
isFast = strategy.isFastSwipe.call(this, e),
startOffset = offsetRatio,
targetOffset = this._calcTargetOffset(offsetRatio, isFast);
startOffset = this._fitOffset(startOffset, this.elastic);
targetOffset = this._fitOffset(targetOffset, false);
this._fireEvent(SWIPE_END_EVENT, e, {
offset: startOffset,
targetOffset: targetOffset
})
},
_fitOffset: function(offset, elastic) {
var strategy = this._getStrategy(),
bounds = strategy.getBounds.call(this);
if (offset < -bounds[0])
return elastic ? (-2 * bounds[0] + offset) / 3 : -bounds[0];
if (offset > bounds[1])
return elastic ? (2 * bounds[1] + offset) / 3 : bounds[1];
return offset
},
_calcTargetOffset: function(offsetRatio, isFast) {
var result;
if (isFast) {
result = Math.ceil(Math.abs(offsetRatio));
if (offsetRatio < 0)
result = -result
}
else
result = Math.round(offsetRatio);
return result
}
});
ui.gestureEmitters.push({
emitter: SwipeEmitter,
events: [SWIPE_START_EVENT, SWIPE_EVENT, SWIPE_END_EVENT]
})
})(jQuery, DevExpress);
/*! Module core, file ui.dragEmitter.js */
(function($, DX, undefined) {
var ui = DX.ui,
utils = DX.utils,
events = ui.events,
wrapToArray = utils.wrapToArray;
var DRAG_START_EVENT = "dxdragstart",
DRAG_EVENT = "dxdrag",
DRAG_END_EVENT = "dxdragend",
DRAG_ENTER_EVENT = "dxdragenter",
DRAG_LEAVE_EVENT = "dxdragleave",
DROP_EVENT = "dxdrop";
var knownDropTargets = [],
knownDropTargetConfigs = [];
var dropTargetRegistration = {
setup: function(element, data) {
var knownDropTarget = $.inArray(element, knownDropTargets) !== -1;
if (!knownDropTarget) {
knownDropTargets.push(element);
knownDropTargetConfigs.push(data || {})
}
},
teardown: function(element, data) {
var elementEvents = $._data(element, "events"),
handlersCount = 0;
$.each([DRAG_ENTER_EVENT, DRAG_LEAVE_EVENT, DROP_EVENT], function(_, eventName) {
var eventHandlers = elementEvents[eventName];
if (eventHandlers)
handlersCount += eventHandlers.length
});
if (!handlersCount) {
var index = $.inArray(element, knownDropTargets);
knownDropTargets.splice(index, 1);
knownDropTargetConfigs.splice(index, 1)
}
}
};
events.registerEvent(DRAG_ENTER_EVENT, dropTargetRegistration);
events.registerEvent(DRAG_LEAVE_EVENT, dropTargetRegistration);
events.registerEvent(DROP_EVENT, dropTargetRegistration);
var getItemConfig = function($element) {
var dropTargetIndex = $.inArray($element.get(0), knownDropTargets);
return knownDropTargetConfigs[dropTargetIndex]
};
var getItemPosition = function($element) {
var dropTargetConfig = getItemConfig($element);
if (dropTargetConfig.itemPositionFunc)
return dropTargetConfig.itemPositionFunc();
else
return $element.offset()
};
var getItemSize = function($element) {
var dropTargetConfig = getItemConfig($element);
if (dropTargetConfig.itemSizeFunc)
return dropTargetConfig.itemSizeFunc();
else
return {
width: $element.width(),
height: $element.height()
}
};
var DragEmitter = ui.GestureEmitter.inherit({
ctor: function(element) {
this.callBase(element);
this.direction = "both"
},
init: function(e) {
var eventData = events.eventData(e);
this._startEventData = eventData
},
start: function(e) {
e = this._fireEvent(DRAG_START_EVENT, e);
this._maxLeftOffset = e.maxLeftOffset;
this._maxRightOffset = e.maxRightOffset;
this._maxTopOffset = e.maxTopOffset;
this._maxBottomOffset = e.maxBottomOffset;
var dropTargets = wrapToArray(e.targetElements || knownDropTargets);
this._$dropTargetElements = $.map(dropTargets, function(element) {
return $(element)
})
},
move: function(e) {
var eventData = events.eventData(e),
dragOffset = this._calculateOffset(eventData);
this._fireEvent(DRAG_EVENT, e, {offset: dragOffset});
this._processDropTargets(e, dragOffset);
e.preventDefault()
},
_calculateOffset: function(eventData) {
return {
x: this._calculateXOffset(eventData),
y: this._calculateYOffset(eventData)
}
},
_calculateXOffset: function(eventData) {
if (this.direction !== "vertical") {
var offset = eventData.x - this._startEventData.x;
return this._fitOffset(offset, this._maxLeftOffset, this._maxRightOffset)
}
return 0
},
_calculateYOffset: function(eventData) {
if (this.direction !== "horizontal") {
var offset = eventData.y - this._startEventData.y;
return this._fitOffset(offset, this._maxTopOffset, this._maxBottomOffset)
}
return 0
},
_fitOffset: function(offset, minOffset, maxOffset) {
if (minOffset != null)
offset = Math.max(offset, -minOffset);
if (maxOffset != null)
offset = Math.min(offset, maxOffset);
return offset
},
_processDropTargets: function(e, dragOffset) {
var target = this._findDropTarget(e),
sameTarget = target === this._$currentDropTarget;
if (!sameTarget) {
this._fireDropTargetEvent(e, DRAG_LEAVE_EVENT);
this._$currentDropTarget = target;
this._fireDropTargetEvent(e, DRAG_ENTER_EVENT)
}
},
_fireDropTargetEvent: function(event, eventName) {
if (!this._$currentDropTarget)
return;
var eventData = {
type: eventName,
originalEvent: event,
draggingElement: this._$element.get(0),
target: this._$currentDropTarget.get(0)
};
events.fireEvent(eventData)
},
_findDropTarget: function(e) {
var that = this,
$result;
$.each(this._$dropTargetElements, function(_, $target) {
if (that._checkDropTarget($target, e)) {
$result = $target;
return false
}
});
return $result
},
_checkDropTarget: function($target, e) {
var isDraggingElement = $target.get(0) === this._$element.get(0);
if (isDraggingElement)
return false;
var targetPosition = getItemPosition($target);
if (e.pageX < targetPosition.left)
return false;
if (e.pageY < targetPosition.top)
return false;
var targetSize = getItemSize($target);
if (e.pageX > targetPosition.left + targetSize.width)
return false;
if (e.pageY > targetPosition.top + targetSize.height)
return false;
return $target
},
end: function(e) {
var eventData = events.eventData(e);
this._fireEvent(DRAG_END_EVENT, e, {offset: this._calculateOffset(eventData)});
this._fireDropTargetEvent(e, DROP_EVENT);
delete this._$currentDropTarget
}
});
ui.gestureEmitters.push({
emitter: DragEmitter,
events: [DRAG_START_EVENT, DRAG_EVENT, DRAG_END_EVENT]
});
DX.ui.events.__internals = DX.ui.events.__internals || {};
$.extend(DX.ui.events.__internals, {dropTargets: knownDropTargets})
})(jQuery, DevExpress);
/*! Module core, file ui.events.gesture.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events,
utils = DX.utils;
var abs = Math.abs;
var GESTURE_EVENT = "dxGesture",
GESTURE_EVENT_DATA = "dxGestureEmitter",
GESTURE_LOCK_KEY = "dxGestureLock",
GESTURE_UNLOCK_TIMEOUT = 400,
TOUCH_BOUNDARY = 10,
HORIZONTAL = "horizontal",
VERTICAL = "vertical",
BOTH = "both";
var GestureEventManager = DX.Class.inherit({
SLEEP: 0,
INITED: 1,
STARTED: 2,
ctor: function() {
this._attachHandlers();
this.reset()
},
_attachHandlers: function() {
$(document).on(events.addNamespace("dxpointerdown", GESTURE_EVENT), $.proxy(this._handlePointerDown, this)).on(events.addNamespace("dxpointermove", GESTURE_EVENT), $.proxy(this._handlePointerMove, this)).on(events.addNamespace("dxpointerup dxpointercancel", GESTURE_EVENT), $.proxy(this._handlePointerUp, this)).on(events.addNamespace("dxmousewheel", GESTURE_EVENT), $.proxy(this._handleMouseWheel, this))
},
_eachEmitter: function(callback) {
$.each(this._activeEmitters || {}, function(direction, emitter) {
return callback(emitter, direction)
})
},
_noEmitters: function() {
return $.isEmptyObject(this._activeEmitters)
},
reset: function() {
this._eachEmitter(function(emitter) {
emitter.removeCancelCallback()
});
this._forgetGesture();
this._stage = this.SLEEP;
this._activeEmitters = {}
},
_handlePointerDown: function(e) {
if (events.needSkipEvent(e) || events.hasTouches(e) > 1)
return;
this.reset();
this._activeEmitters = this._closestEmitter(e);
if (this._noEmitters())
return;
this._startEvent = e;
this._startEventData = events.eventData(e);
this._stage = this.INITED;
this._applyToActive("init", e)
},
_applyToActive: function(method) {
var args = $.makeArray(arguments).slice(1);
this._eachEmitter(function(emitter) {
if (method in emitter)
emitter[method].apply(emitter, args)
})
},
_closestEmitter: function(e) {
var result = {},
foundForAllDirections = false,
$element = $(e.target);
while ($element.length && !foundForAllDirections) {
var emitter = $element.data(GESTURE_EVENT_DATA);
if (emitter && emitter.validate(e)) {
var direction = emitter.getDirection(e);
if (direction) {
emitter.addCancelCallback($.proxy(this._handleCancel, this, emitter, e));
result[direction] = result[direction] || emitter
}
}
foundForAllDirections = result[HORIZONTAL] && result[VERTICAL] || result[BOTH];
$element = $element.parent()
}
return result
},
_handleCancel: function(canceledEmitter, e) {
var canceledDirection;
this._eachEmitter(function(emitter, direction) {
if (emitter === canceledEmitter) {
canceledDirection = direction;
emitter.removeCancelCallback()
}
});
this._forgetGesture([canceledEmitter]);
this._cancelEmitter(canceledEmitter, e);
if (this._noEmitters())
this.reset()
},
_handlePointerMove: function(e) {
if (this._stage === this.INITED && this._directionDetected(e))
this._handleStart(e);
if (this._stage === this.STARTED)
this._handleMove(e)
},
_directionDetected: function(e) {
var delta = events.eventDelta(this._startEventData, events.eventData(e));
return delta.x || delta.y
},
_handleStart: function(e) {
this._filterEmitters(e);
if (this._noEmitters())
return;
this._resetActiveElement();
this._applyToActive("start", this._startEvent);
this._stage = this.STARTED
},
_resetActiveElement: function() {
if (DX.devices.real().platform !== "ios")
return;
this._eachEmitter(function(emitter) {
if ($(":focus", emitter.getElement()).length)
utils.resetActiveElement()
})
},
_filterEmitters: function(e) {
this._filterByDirection(e);
if (this._emitersAmount() > 1)
this._takeFirstEmitter()
},
_emitersAmount: function() {
var result = 0;
this._eachEmitter(function() {
result++
});
return result
},
_filterByDirection: function(e) {
var delta = events.eventDelta(this._startEventData, events.eventData(e)),
horizontalMove = abs(delta.y) < abs(delta.x),
verticalMove = abs(delta.y) > abs(delta.x),
horizontalEmmiter = this._activeEmitters[HORIZONTAL],
verticalEmmiter = this._activeEmitters[VERTICAL],
bothEmitter = this._activeEmitters[BOTH],
existsHorizontalEmitter = horizontalEmmiter || bothEmitter,
existsVerticalEmitter = verticalEmmiter || bothEmitter;
if (horizontalMove && existsHorizontalEmitter)
this._cancelEmitter(verticalEmmiter, e);
else if (verticalMove && existsVerticalEmitter)
this._cancelEmitter(horizontalEmmiter, e)
},
_cancelEmitter: function(canceledEmmiter, e) {
if (!canceledEmmiter)
return;
canceledEmmiter.cancel(e);
delete this._activeEmitters[canceledEmmiter.getDirection(e)]
},
_takeFirstEmitter: function() {
var activeEmitters = {};
this._eachEmitter(function(emitter, direction) {
activeEmitters[direction] = emitter;
return false
});
this._activeEmitters = activeEmitters
},
_prepareGesture: function() {
this._gestureLocked = true;
clearTimeout(this._gestureEndTimer);
this._eachEmitter(function(emitter) {
emitter.getElement().data(GESTURE_LOCK_KEY, true)
});
ui.feedback.reset()
},
_handleMove: function(e) {
if (!this._gestureLocked) {
var delta = events.eventDelta(this._startEventData, events.eventData(e));
if (abs(delta.x) > TOUCH_BOUNDARY || abs(delta.y) > TOUCH_BOUNDARY) {
events.handleGestureEvent(e, GESTURE_EVENT);
this._prepareGesture()
}
}
this._applyToActive("move", e)
},
_forgetGesture: function(activeEmitters) {
activeEmitters = activeEmitters || this._activeEmitters;
if (this._noEmitters())
return;
this._gestureLocked = false;
this._gestureEndTimer = setTimeout(function() {
$.each(activeEmitters, function(_, emitter) {
emitter.getElement().data(GESTURE_LOCK_KEY, false)
})
}, GESTURE_UNLOCK_TIMEOUT)
},
_handlePointerUp: function(e) {
if (!DX.devices.isRippleEmulator() && events.hasTouches(e))
return;
if (this._stage === this.STARTED)
this._applyToActive("end", e);
else if (this._stage === this.INITED)
this._applyToActive("stop", e);
this.reset()
},
_handleMouseWheel: function(e) {
this._handlePointerDown(e);
if (this._stage !== this.INITED)
return;
this._takeFirstEmitter();
this._eachEmitter(function(emitter, direction) {
var prop = direction !== "horizontal" ? "pageY" : "pageX";
e[prop] += e.delta
});
this._handlePointerMove(e);
this._handlePointerUp(e)
},
isActive: function(element) {
var result = false;
this._eachEmitter(function(emitter) {
result = result || emitter.getElement().is(element)
});
return result
}
});
var gestureEventManager = new GestureEventManager;
var registerEmitter = function(emitterConfig) {
var emitterClass = emitterConfig.emitter;
$.each(emitterConfig.events, function(_, eventName) {
events.registerEvent(eventName, {
noBubble: true,
setup: function(element, data) {
var emitter = $(element).data(GESTURE_EVENT_DATA) || new emitterClass(element);
emitter.configurate(data);
$(element).data(GESTURE_EVENT_DATA, emitter)
},
teardown: function(element) {
if (gestureEventManager.isActive(element))
gestureEventManager.reset();
$(element).removeData(GESTURE_EVENT_DATA)
}
})
})
};
$.each(ui.gestureEmitters, function(_, emitterConfig) {
registerEmitter(emitterConfig)
});
events.__internals = events.__internals || {};
$.extend(events.__internals, {registerEmitter: registerEmitter})
})(jQuery, DevExpress);
/*! Module core, file ui.widget.js */
(function($, DX, undefined) {
var ui = DX.ui,
UI_FEEDBACK = "UIFeedback",
UI_FEEDBACK_CLASS = "dx-feedback",
ACTIVE_STATE_CLASS = "dx-state-active",
DISABLED_STATE_CLASS = "dx-state-disabled",
INVISIBLE_STATE_CLASS = "dx-state-invisible",
HOVER_STATE_CLASS = "dx-state-hover",
FEEDBACK_SHOW_TIMEOUT = 30,
FEEDBACK_HIDE_TIMEOUT = 400,
HOVER_START = "dxhoverstart",
HOVER_END = "dxhoverend",
ANONYMOUS_TEMPLATE_NAME = "template",
TEMPLATE_SELECTOR = "[data-options*='dxTemplate']",
TEMPLATES_DATA_KEY = "dxTemplates";
var getTemplateOptions = function(element) {
var options = $(element).data("options");
if ($.trim(options).charAt(0) !== "{")
options = "{" + options + "}";
return new Function("return " + options)().dxTemplate
};
var activeElement,
events = ui.events;
ui.feedback = {reset: function() {
handleEnd(true)
}};
ui.Widget = DX.DOMComponent.inherit({
NAME: "Widget",
NAMESPACE: ui,
_setDefaultOptions: function() {
this.callBase();
this.option({
disabled: false,
visible: true,
activeStateEnabled: true,
width: undefined,
height: undefined,
contentReadyAction: null,
hoverStateEnabled: false
})
},
_init: function() {
this.callBase();
this._feedbackShowTimeout = FEEDBACK_SHOW_TIMEOUT;
this._feedbackHideTimeout = FEEDBACK_HIDE_TIMEOUT;
if (this._templatesSupported()) {
this._initTemplates();
this._initContentReadyAction()
}
},
_templatesSupported: function() {
return this._renderContentImpl !== DX.abstract
},
_initTemplates: function() {
var that = this,
templates = {},
dataTemplateElements = this._element().data(TEMPLATES_DATA_KEY),
templateElements = dataTemplateElements ? dataTemplateElements : this._element().contents().filter(TEMPLATE_SELECTOR);
this._templateProvider = new ui.TemplateProvider;
this._templateClass = this._templateProvider.getTemplateClass(this);
if (templateElements.length) {
var templatesMap = {};
templateElements.each(function() {
var templateOptions = getTemplateOptions(this);
if (!templateOptions)
return;
if (!templateOptions.name)
throw Error("Template name was not specified");
templatesMap[templateOptions.name] = templatesMap[templateOptions.name] || [];
templatesMap[templateOptions.name].push(this)
});
$.each(templatesMap, function(templateName, value) {
var deviceTemplate = that._findTemplateByDevice(value);
if (deviceTemplate)
templates[templateName] = that._createTemplate(deviceTemplate)
})
}
else
templates[ANONYMOUS_TEMPLATE_NAME] = that._createTemplate(that._element().contents());
this.option("_templates", templates)
},
_getTemplateByOption: function(optionName) {
return this._getTemplate(this.option(optionName))
},
_getTemplate: function(templateName) {
var result = this._acquireTemplate.apply(this, arguments);
if (!result && this._templateProvider.supportDefaultTemplate(this)) {
result = this._templateProvider.getDefaultTemplate(this);
if (!result)
throw Error(DX.utils.stringFormat("Template \"{0}\" was not found and no default template specified!", templateName));
}
return result
},
_acquireTemplate: function(templateSource) {
if (templateSource == null)
return templateSource;
if (templateSource instanceof this._templateClass)
return templateSource;
if (templateSource.nodeType || templateSource.jquery) {
templateSource = $(templateSource);
if (templateSource.is("script"))
templateSource = templateSource.html();
return this._createTemplate(templateSource)
}
if (typeof templateSource === "string")
return this.option("_templates")[templateSource];
if ($.isFunction(templateSource)) {
var args = $.makeArray(arguments).slice(1);
return this._acquireTemplate(templateSource.apply(this, args))
}
return this._acquireTemplate(templateSource.toString())
},
_createTemplate: function(element) {
return new this._templateClass(element, this)
},
_findTemplateByDevice: function(templates) {
var suitableTemplate = DX.utils.findBestMatches(DX.devices.current(), templates, function(template) {
return getTemplateOptions(template)
})[0];
$.each(templates, function(index, template) {
if (template !== suitableTemplate)
$(template).remove()
});
return suitableTemplate
},
_cleanTemplates: function() {
var that = this;
$.each(this.option("_templates"), function(templateName, template) {
if (that === template.owner())
template.dispose()
})
},
_initContentReadyAction: function() {
this._contentReadyAction = this._createActionByOption("contentReadyAction", {excludeValidators: ["gesture", "designMode", "disabled"]})
},
_render: function() {
this.callBase();
this._element().addClass("dx-widget");
this._toggleDisabledState(this.option("disabled"));
this._toggleVisibility(this.option("visible"));
this._refreshFeedback();
this._renderDimensions();
if (this._templatesSupported())
this._renderContent();
this._attachHoverEvents()
},
_renderContent: function() {
this._renderContentImpl();
this._fireContentReadyAction()
},
_renderContentImpl: DX.abstract,
_fireContentReadyAction: function() {
this._contentReadyAction({excludeValidators: ["disabled", "gesture"]})
},
_dispose: function() {
if (this._templatesSupported())
this._cleanTemplates();
this._contentReadyAction = null;
this._clearTimers();
if (activeElement && activeElement.closest(this._element()).length)
activeElement = null;
this.callBase()
},
_clean: function() {
this.callBase();
this._element().empty()
},
_clearTimers: function() {
clearTimeout(this._feedbackHideTimer);
clearTimeout(this._feedbackShowTimer)
},
_toggleVisibility: function(visible) {
this._element().toggleClass(INVISIBLE_STATE_CLASS, !visible)
},
_attachHoverEvents: function() {
var that = this,
hoverableSelector = that._activeStateUnit,
nameStart = events.addNamespace(HOVER_START, UI_FEEDBACK),
nameEnd = events.addNamespace(HOVER_END, UI_FEEDBACK);
that._element().off(nameStart, hoverableSelector).off(nameEnd, hoverableSelector);
if (this.option("hoverStateEnabled")) {
var startAction = new DX.Action(function(args) {
var $target = args.element;
that._refreshHoveredElement($target)
});
that._element().on(nameStart, hoverableSelector, {selector: hoverableSelector}, function(e) {
startAction.execute({element: $(e.target)})
}).on(nameEnd, hoverableSelector, {selector: hoverableSelector}, function(e) {
e.stopImmediatePropagation();
that._forgetHoveredElement()
})
}
else
this._toggleHoverClass(false)
},
_refreshHoveredElement: function(hoveredElement) {
var selector = this._activeStateUnit || this._element();
this._forgetHoveredElement();
this._hoveredElement = hoveredElement.closest(selector);
this._toggleHoverClass(true)
},
_forgetHoveredElement: function() {
this._toggleHoverClass(false);
delete this._hoveredElement
},
_toggleHoverClass: function(value) {
if (this._hoveredElement)
this._hoveredElement.toggleClass(HOVER_STATE_CLASS, value && this.option("hoverStateEnabled"))
},
_renderDimensions: function() {
var width = this.option("width"),
height = this.option("height");
this._setDimension(width, "width");
this._setDimension(height, "height")
},
_setDimension: function(dimensionSize, dimension) {
var $element = this._element();
dimensionSize = $.isFunction(dimensionSize) ? dimensionSize() : dimensionSize;
if ($.isNumeric(dimensionSize))
dimensionSize = dimensionSize + "px";
if (!dimensionSize && dimension === "width")
dimensionSize = this._calculateWidth();
$element.css(dimension, dimensionSize)
},
_calculateWidth: function() {
var $element = this._element(),
explicitWidth = $element[0].style.width,
calculatedWidth;
if (explicitWidth[explicitWidth.length - 1] === "%" && !this.option("width"))
return explicitWidth;
else
calculatedWidth = explicitWidth && explicitWidth !== "auto" && explicitWidth !== "inherit" ? $element.outerWidth() : this.option("width");
return calculatedWidth
},
_refreshFeedback: function() {
if (this._feedbackDisabled()) {
this._feedbackOff(true);
this._element().removeClass(UI_FEEDBACK_CLASS)
}
else
this._element().addClass(UI_FEEDBACK_CLASS)
},
_feedbackDisabled: function() {
return !this.option("activeStateEnabled") || this.option("disabled")
},
_feedbackOn: function(element, immediate) {
if (this._feedbackDisabled())
return;
this._clearTimers();
if (immediate)
this._feedbackShow(element);
else
this._feedbackShowTimer = window.setTimeout($.proxy(this._feedbackShow, this, element), this._feedbackShowTimeout);
this._saveActiveElement()
},
_feedbackShow: function(element) {
var activeStateElement = this._element();
if (this._activeStateUnit)
activeStateElement = $(element).closest(this._activeStateUnit);
if (!activeStateElement.hasClass(DISABLED_STATE_CLASS)) {
activeStateElement.addClass(ACTIVE_STATE_CLASS);
this._toggleHoverClass(false)
}
},
_saveActiveElement: function() {
activeElement = this._element()
},
_feedbackOff: function(immediate) {
this._clearTimers();
if (immediate)
this._feedbackHide();
else
this._feedbackHideTimer = window.setTimeout($.proxy(this._feedbackHide, this), this._feedbackHideTimeout)
},
_feedbackHide: function() {
var activeStateElement = this._element();
if (this._activeStateUnit)
activeStateElement = activeStateElement.find(this._activeStateUnit);
activeStateElement.removeClass(ACTIVE_STATE_CLASS);
this._toggleHoverClass(!this.option("disabled"));
this._clearActiveElement()
},
_clearActiveElement: function() {
var rootDomElement = this._element().get(0),
activeDomElement = activeElement && activeElement.get(0);
if (activeDomElement && (activeDomElement === rootDomElement || $.contains(rootDomElement, activeDomElement)))
activeElement = null
},
_toggleDisabledState: function(value) {
this._element().toggleClass(DISABLED_STATE_CLASS, Boolean(value));
this._toggleHoverClass(!value)
},
_optionChanged: function(name, value) {
switch (name) {
case"disabled":
this._toggleDisabledState(value);
this._refreshFeedback();
break;
case"activeStateEnabled":
this._refreshFeedback();
break;
case"hoverStateEnabled":
this._attachHoverEvents();
break;
case"visible":
this._toggleVisibility(value);
break;
case"width":
case"height":
this._renderDimensions();
break;
case"contentReadyAction":
this._initContentReadyAction();
break;
case"_templates":
this._refresh();
break;
default:
this.callBase.apply(this, arguments)
}
},
repaint: function() {
this._refresh()
}
});
var handleStart = function(args, immediate) {
var e = args.jQueryEvent,
$target = args.element,
widget;
if (events.needSkipEvent(e))
return;
if (activeElement) {
widget = getWidget(activeElement);
if (widget)
widget._feedbackOff(true)
}
var closestFeedbackElement = $target.closest("." + UI_FEEDBACK_CLASS);
if (closestFeedbackElement.length) {
widget = getWidget(closestFeedbackElement);
if (!widget)
return;
widget._feedbackOn($target, immediate);
if (immediate)
widget._feedbackOff()
}
};
var handleEnd = function(immediate) {
if (!activeElement)
return;
var widget = getWidget(activeElement);
if (widget)
widget._feedbackOff(immediate)
};
var getWidget = function(widgetElement) {
var result;
$.each(widgetElement.data("dxComponents") || [], function(index, componentName) {
if (ui[componentName] && ui[componentName].subclassOf(ui.Widget)) {
result = widgetElement.data(componentName);
return false
}
});
return result
};
$(function() {
var startAction = new DX.Action(handleStart);
$(document).on(events.addNamespace("dxpointerdown", UI_FEEDBACK), function(e) {
startAction.execute({
jQueryEvent: e,
element: $(e.target)
})
}).on(events.addNamespace("dxpointerup dxpointercancel", UI_FEEDBACK), function(e) {
var activeElementClicked = activeElement && $(e.target).closest("." + UI_FEEDBACK_CLASS).get(0) === activeElement.get(0);
if (activeElementClicked)
startAction.execute({
jQueryEvent: e,
element: $(e.target)
}, true);
handleEnd()
})
})
})(jQuery, DevExpress);
/*! Module core, file ui.editor.js */
(function($, DX, undefined) {
var ui = DX.ui;
DX.registerComponent("dxEditor", ui.Widget.inherit({
_setDefaultOptions: function() {
this.callBase();
this.option({
value: undefined,
valueChangeAction: undefined
})
},
_recreateValueChangeAction: function() {
this._valueChangeAction = this._createActionByOption("valueChangeAction")
},
_suppressValueChangeAction: function() {
this._valueChangeActionSuppressed = true
},
_resumeValueChangeAction: function() {
this._valueChangeActionSuppressed = false
},
_render: function() {
this._recreateValueChangeAction();
this.callBase()
},
_raiseValueChangeAction: function(value, previousValue, extraArguments) {
var args = {
value: value,
previousValue: previousValue,
jQueryEvent: this._valueChangeEventInstance
};
if (extraArguments)
args = $.extend(args, extraArguments);
this._valueChangeAction(args)
},
_optionChanged: function(name, value, previousValue) {
switch (name) {
case"valueChangeAction":
this._recreateValueChangeAction();
break;
case"value":
if (!this._valueChangeActionSuppressed)
this._raiseValueChangeAction(value, previousValue);
this._valueChangeEventInstance = undefined;
break;
default:
this.callBase.apply(this, arguments)
}
}
}))
})(jQuery, DevExpress);
/*! Module core, file ui.template.js */
(function($, DX, undefined) {
var isString = DX.utils.isString;
var currentTemplateEngine;
var templateEngines = [];
var BaseTemplate = DevExpress.Class.inherit({
_compile: function(html, element) {
return element
},
_render: function(template, data) {
return template
},
ctor: function(element) {
this._element = $(element);
if (this._element.length === 1) {
if (this._element[0].nodeName.toLowerCase() !== "script")
this._element = $("
").append(this._element);
this._template = this._compile(this._element.html() || "", this._element)
}
},
render: function(container, data) {
var result;
if (this._template) {
result = this._render(this._template, data);
if (isString(result))
result = $.parseHTML(result);
result = $(result);
if (container)
container.append(result);
return result
}
},
owner: $.noop,
dispose: $.noop
});
var createTemplateEngine = function(options) {
if (options && options.compile && options.render)
return BaseTemplate.inherit({
allowRenderToDetachedContainer: options.allowRenderToDetachedContainer !== false,
_compile: options.compile,
_render: options.render
});
else
throw Error("Template Engine must contains compile and render methods");
};
if (window.ko) {
var koCustomTemplateEngine = function(){};
koCustomTemplateEngine.prototype = ko.utils.extend(new ko.templateEngine, {
renderTemplateSource: function(templateSource, bindingContext, options) {
var precompiledTemplate = templateSource["data"]("precompiledTemplate");
if (!precompiledTemplate) {
precompiledTemplate = new currentTemplateEngine(templateSource.domElement);
templateSource["data"]("precompiledTemplate", precompiledTemplate)
}
return precompiledTemplate.render(null, bindingContext.$data)
},
allowTemplateRewriting: false
})
}
DevExpress.ui.setTemplateEngine = function(templateEngine) {
if (isString(templateEngine)) {
currentTemplateEngine = templateEngines && templateEngines[templateEngine];
if (!currentTemplateEngine && templateEngine !== "default")
throw Error(DX.utils.stringFormat("Template Engine \"{0}\" is not supported", templateEngine));
}
else
currentTemplateEngine = createTemplateEngine(templateEngine) || currentTemplateEngine;
if (window.ko)
ko.setTemplateEngine(currentTemplateEngine ? new koCustomTemplateEngine : new ko.nativeTemplateEngine)
};
DevExpress.ui.TemplateProvider = DevExpress.ui.TemplateProvider.inherit({getTemplateClass: function() {
if (currentTemplateEngine)
return currentTemplateEngine;
return this.callBase.apply(this, arguments)
}});
var registerTemplateEngine = function(name, templateOptions) {
templateEngines[name] = createTemplateEngine(templateOptions)
};
registerTemplateEngine("jquery-tmpl", {
compile: function(html, element) {
return element
},
render: function(template, data) {
return template.tmpl(data)
}
});
registerTemplateEngine("jsrender", {
compile: function(html) {
return $.templates(html)
},
render: function(template, data) {
return template.render(data)
}
});
registerTemplateEngine("mustache", {
compile: function(html) {
return Mustache.compile(html)
},
render: function(template, data) {
return template(data)
}
});
registerTemplateEngine("hogan", {
compile: function(html) {
return Hogan.compile(html)
},
render: function(template, data) {
return template.render(data)
}
});
registerTemplateEngine("underscore", {
compile: function(html) {
return _.template(html)
},
render: function(template, data) {
return template(data)
}
});
registerTemplateEngine("handlebars", {
compile: function(html) {
return Handlebars.compile(html)
},
render: function(template, data) {
return template(data)
}
});
registerTemplateEngine("doT", {
compile: function(html) {
return doT.template(html)
},
render: function(template, data) {
return template(data)
}
})
})(jQuery, DevExpress);
/*! Module core, file ui.collectionContainerWidget.js */
(function($, DX, undefined) {
var ui = DX.ui,
events = ui.events;
var CollectionContainerWidget = ui.Widget.inherit({
_setDefaultOptions: function() {
this.callBase();
this.option({
items: [],
itemTemplate: "item",
itemRender: null,
itemRenderedAction: null,
itemClickAction: null,
itemHoldAction: null,
itemHoldTimeout: 750,
noDataText: Globalize.localize("dxCollectionContainerWidget-noDataText"),
dataSource: null,
selectedIndex: -1,
itemSelectAction: null,
itemTemplateProperty: "template"
})
},
_init: function() {
this.callBase();
this._cleanRenderedItems();
this._refreshDataSource()
},
_dataSourceOptions: function() {
var options = {
paginate: false,
_preferSync: false
};
if ($.isArray(this.option("dataSource")))
options._preferSync = true;
return options
},
_cleanRenderedItems: function() {
this._renderedItemsCount = 0
},
_fireSelectItemEvent: function(index, prevIndex) {
if (this._selectionEnabled()) {
this._updateSelectedIndex(index, prevIndex);
this._handleItemEvent(this._selectedItemElement(index), "itemSelectAction", {
selectedIndex: index,
previousIndex: prevIndex
}, {excludeValidators: ["gesture", "disabled"]})
}
},
_optionChanged: function(name, value, prevValue) {
switch (name) {
case"items":
case"itemTemplateProperty":
if (this._selectionEnabled()) {
var itemsCount = value && value.length || 0,
maxIndex = Math.max(itemsCount - 1, 0);
if (maxIndex < this.option("selectedIndex"))
this.option("selectedIndex", 0)
}
this._cleanRenderedItems();
this._invalidate();
break;
case"dataSource":
this._refreshDataSource();
if (!this._dataSource)
this.option("items", []);
this._renderEmptyMessage();
break;
case"noDataText":
this._renderEmptyMessage();
break;
case"itemTemplate":
this._invalidate();
break;
case"itemRender":
this._itemRender = null;
this._invalidate();
break;
case"itemRenderedAction":
this._createItemRenderAction();
break;
case"itemClickAction":
break;
case"itemHoldAction":
case"itemHoldTimeout":
this._attachHoldEvent();
break;
case"selectedIndex":
this._fireSelectItemEvent(value, prevValue);
break;
case"itemSelectAction":
break;
default:
this.callBase(name, value, prevValue)
}
},
_expectNextPageLoading: function() {
this._startIndexForAppendedItems = 0
},
_expectLastItemLoading: function() {
this._startIndexForAppendedItems = -1
},
_forgetNextPageLoading: function() {
this._startIndexForAppendedItems = null
},
_handleDataSourceChanged: function(newItems) {
var items = this.option("items");
if (this._initialized && items && this._shouldAppendItems()) {
this._renderedItemsCount = items.length;
if (!this._dataSource.isLastPage() || this._startIndexForAppendedItems !== -1)
this.option().items = items.concat(newItems.slice(this._startIndexForAppendedItems));
this._renderContent();
this._forgetNextPageLoading()
}
else
this.option("items", newItems)
},
_handleDataSourceLoadError: function() {
this._forgetNextPageLoading()
},
_shouldAppendItems: function() {
return this._startIndexForAppendedItems != null && this._allowDinamicItemsAppend()
},
_allowDinamicItemsAppend: function() {
return false
},
_clean: function() {
this._itemContainer().empty()
},
_refresh: function() {
this._cleanRenderedItems();
this.callBase.apply(this, arguments)
},
_itemContainer: function() {
return this._element()
},
_itemClass: DX.abstract,
_itemSelector: function() {
return "." + this._itemClass()
},
_itemDataKey: DX.abstract,
_itemElements: function() {
return this._itemContainer().find(this._itemSelector())
},
_render: function() {
this.callBase();
this._attachClickEvent();
this._attachHoldEvent();
if (this._selectionEnabled()) {
this._renderSelectedIndex(this.option("selectedIndex"));
this._attachSelectedEvent()
}
},
_selectionEnabled: function() {
return this._renderSelectedIndex !== DX.abstract
},
_selectionByClickEnabled: function() {
return true
},
_renderSelectedIndex: DX.abstract,
_attachSelectedEvent: function() {
if (!this._selectionByClickEnabled())
return;
var itemSelector = this._itemSelector(),
itemSelectHandler = this._createAction($.proxy(function(e) {
this._handleItemSelect(e.jQueryEvent)
}, this), {validatingTargetName: "itemElement"}),
eventName = events.addNamespace("dxclick", this.NAME);
this._element().off(eventName, itemSelector).on(eventName, itemSelector, $.proxy(function(e) {
var $itemElement = $(e.target).closest(itemSelector);
itemSelectHandler({
itemElement: $itemElement,
jQueryEvent: e
});
this._handleItemClick(e)
}, this))
},
_handleItemSelect: function(e) {
if (events.needSkipEvent(e))
return;
var items = this.option("items"),
selectedItem = $(e.currentTarget).data(this._itemDataKey()),
selectedItemIndex = $.inArray(selectedItem, items);
this.option("selectedIndex", selectedItemIndex)
},
_updateSelectedIndex: function() {
this._renderSelectedIndex.apply(this, arguments)
},
_selectedItemElement: function(index) {
return this._itemElements().eq(index)
},
_attachClickEvent: function() {
if (this._selectionEnabled() && this._selectionByClickEnabled())
return;
var itemSelector = this._itemSelector(),
eventName = events.addNamespace("dxclick", this.NAME);
this._itemContainer().off(eventName, itemSelector).on(eventName, itemSelector, $.proxy(this._handleItemClick, this))
},
_handleItemClick: function(e) {
this._handleItemJQueryEvent(e, "itemClickAction")
},
_attachHoldEvent: function() {
var $itemContainer = this._itemContainer(),
itemSelector = this._itemSelector(),
eventName = events.addNamespace("dxhold", this.NAME);
$itemContainer.off(eventName, itemSelector);
if (this._shouldAttachHoldEvent())
$itemContainer.on(eventName, itemSelector, {timeout: this.option("itemHoldTimeout")}, $.proxy(this._handleItemHold, this))
},
_shouldAttachHoldEvent: function() {
return this.option("itemHoldAction")
},
_handleItemHold: function(e) {
this._handleItemJQueryEvent(e, "itemHoldAction")
},
_renderContentImpl: function() {
var items = this.option("items") || [];
if (this._renderedItemsCount)
this._renderItems(items.slice(this._renderedItemsCount));
else
this._renderItems(items)
},
_renderItems: function(items) {
if (items.length)
$.each(items, $.proxy(this._renderItem, this));
this._renderEmptyMessage()
},
_renderItem: function(index, itemData, container) {
container = container || this._itemContainer();
var itemRenderer = this._getItemRenderer(),
itemTemplateName = this._getItemTemplateName(itemData),
itemTemplate = this._getTemplate(itemTemplateName, index, itemData),
itemElement,
renderArgs = {
index: index,
item: itemData,
container: container
};
if (itemRenderer)
itemElement = this._createItemByRenderer(itemRenderer, renderArgs);
else if (itemTemplate)
itemElement = this._createItemByTemplate(itemTemplate, renderArgs);
else
itemElement = this._createItemByRenderer(this._itemRenderDefault, renderArgs);
itemElement.addClass(this._itemClass()).data(this._itemDataKey(), itemData);
var postprocessRenderArgs = {
itemElement: itemElement,
itemData: itemData,
itemIndex: index
};
this._postprocessRenderItem(postprocessRenderArgs);
this._getItemRenderAction()({
itemElement: itemElement,
itemData: itemData
});
return itemElement
},
_createItemRenderAction: function() {
return this._itemRenderAction = this._createActionByOption("itemRenderedAction", {
element: this._element(),
excludeValidators: ["gesture", "designMode", "disabled"]
})
},
_getItemRenderAction: function() {
return this._itemRenderAction || this._createItemRenderAction()
},
_getItemRenderer: function() {
this._itemRender = this._itemRender || this.option("itemRender");
return this._itemRender
},
_createItemByRenderer: function(itemRenderer, renderArgs) {
var itemElement = $("
").appendTo(renderArgs.container);
var rendererResult = itemRenderer.call(this, renderArgs.item, renderArgs.index, itemElement);
if (rendererResult != null && itemElement[0] !== rendererResult[0])
itemElement.append(rendererResult);
return itemElement
},
_getItemTemplateName: function(itemData) {
var templateProperty = this.option("itemTemplateProperty");
return itemData && itemData[templateProperty] || this.option("itemTemplate")
},
_createItemByTemplate: function(itemTemplate, renderArgs) {
return itemTemplate.render(renderArgs.container, renderArgs.item, renderArgs.index, "ignoreTarget")
},
_itemRenderDefault: function(item, index, itemElement) {
if ($.isPlainObject(item)) {
if (item.visible !== undefined && !item.visible)
itemElement.hide();
if (item.disabled)
itemElement.addClass("dx-state-disabled");
if (item.text)
itemElement.text(item.text);
if (item.html)
itemElement.html(item.html)
}
else
itemElement.html(String(item))
},
_postprocessRenderItem: $.noop,
_renderEmptyMessage: function() {
if (!this._selectionEnabled()) {
var noDataText = this.option("noDataText"),
items = this.option("items"),
dataSourceLoading = this._dataSource && this._dataSource.isLoading(),
hideNoData = !noDataText || items && items.length || dataSourceLoading;
if (hideNoData && this._$nodata) {
this._$nodata.remove();
this._$nodata = null
}
if (!hideNoData) {
this._$nodata = this._$nodata || $("
").addClass("dx-empty-message");
this._$nodata.appendTo(this._itemContainer()).text(noDataText)
}
}
},
_handleItemJQueryEvent: function(jQueryEvent, handlerOptionName, actionArgs, actionConfig) {
this._handleItemEvent(jQueryEvent.target, handlerOptionName, $.extend(actionArgs, {jQueryEvent: jQueryEvent}), actionConfig)
},
_handleItemEvent: function(initiator, handlerOptionName, actionArgs, actionConfig) {
var action = this._createActionByOption(handlerOptionName, $.extend({validatingTargetName: "itemElement"}, actionConfig));
return this._handleItemEventImpl(initiator, action, actionArgs)
},
_handleItemEventByHandler: function(initiator, handler, actionArgs, actionConfig) {
var action = this._createAction(handler, $.extend({validatingTargetName: "itemElement"}, actionConfig));
return this._handleItemEventImpl(initiator, action, actionArgs)
},
_handleItemEventImpl: function(initiator, action, actionArgs) {
var $itemElement = this._closestItemElement($(initiator));
actionArgs = $.extend({
itemElement: $itemElement,
itemData: this._getItemData($itemElement)
}, actionArgs);
return action(actionArgs)
},
_closestItemElement: function($element) {
return $($element).closest(this._itemSelector())
},
_getItemData: function($itemElement) {
return $itemElement.data(this._itemDataKey())
},
itemElements: function() {
return this._itemElements()
},
itemsContainer: function() {
return this._itemContainer()
}
}).include(ui.DataHelperMixin);
ui.CollectionContainerWidget = CollectionContainerWidget
})(jQuery, DevExpress);
/*! Module core, file ui.tooltip.js */
(function($, DX, undefined) {
var $tooltip = null;
var createTooltip = function(options) {
options = $.extend({position: "top"}, options);
var content = options.content;
delete options.content;
return $("
").html(content).appendTo(DX.overlayTargetContainer()).dxTooltip(options)
};
var removeTooltip = function() {
if (!$tooltip)
return;
$tooltip.remove();
$tooltip = null
};
var tooltip = {
show: function(options) {
removeTooltip();
$tooltip = createTooltip(options);
return $tooltip.dxTooltip("show")
},
hide: function() {
if (!$tooltip)
return $.when();
return $tooltip.dxTooltip("hide").done(removeTooltip).promise()
}
};
DX.ui.tooltip = tooltip
})(jQuery, DevExpress)
}
if (!DevExpress.MOD_VIZ_CORE) {
if (!window.DevExpress)
throw Error('Required module is not referenced: core');
/*! Module viz-core, file namespaces.js */
(function(DevExpress) {
DevExpress.viz = {}
})(DevExpress);
/*! Module viz-core, file namespaces.js */
(function(DevExpress) {
DevExpress.viz.core = {}
})(DevExpress);
/*! Module viz-core, file errorsWarnings.js */
(function(DevExpress) {
DevExpress.viz.core.errorsWarnings = {
E2001: "Invalid data source",
E2002: "Axis type and data type are incompatible",
E2003: "\"{0}\" data source field contains data of unsupported type",
E2004: "\"{0}\" data source field is inconsistent",
E2101: "Unknown series type was specified: {0}",
E2102: "Ambiguity occurred between two value axes with the same name",
E2103: "\"{0}\" option must be a function",
E2104: "Invalid logarithm base",
E2105: "Invalid value of a \"{0}\"",
E2106: "Invalid visible range",
E2201: "Invalid type of data source field",
E2202: "Invalid scale {0} value",
E2203: "The \"{0}\" field of the \"selectedRange\" configuration object is not valid",
W2001: "{0} cannot be drawn because its container is invisible",
W2002: "The {0} data field is absent",
W2003: "Tick interval is too small",
W2101: "\"{0}\" pane does not exist; \"{1}\" pane is used instead",
W2102: "Value axis with the \"{0}\" name was created automatically",
W2103: "Chart title was hidden due to container size",
W2104: "Legend was hidden due to container size",
W2105: "Title of \"{0}\" axis was hidden due to container size",
W2106: "Labels of \"{0}\" axis were hidden due to container size",
W2301: "Invalid value range"
}
})(DevExpress);
/*! Module viz-core, file tickProvider.js */
(function($, DX, undefined) {
var utils = DX.utils,
math = Math,
mathCeil = math.ceil,
mathFloor = math.floor,
mathAbs = math.abs,
mathRound = math.round,
core = DX.viz.core;
var TICKS_COUNT_LIMIT = 2000;
core.outOfScreen = {
x: -1000,
y: -1000
};
core.tickIntervalCalculator = {
_defaultNumberMultipliers: [1, 2, 3, 5],
_defaultGridSpacingFactor: 30,
_getCommonTickInterval: function(deltaCoef, numberMultipliers) {
var factor,
result = 0,
hasResult = false,
i;
for (factor = 1; !hasResult; factor *= 10)
for (i = 0; i < numberMultipliers.length; i++) {
result = numberMultipliers[i] * factor;
if (deltaCoef <= result) {
hasResult = true;
break
}
}
return result
},
_getNumericTickInterval: function(deltaCoef, numberMultipliers) {
var factor,
result = 0,
newResult,
hasResult = false,
i;
if (deltaCoef > 1.0)
result = this._getCommonTickInterval(deltaCoef, numberMultipliers);
else if (deltaCoef > 0) {
result = 1;
for (factor = 0.1; !hasResult; factor /= 10)
for (i = numberMultipliers.length - 1; i >= 0; i--) {
newResult = numberMultipliers[i] * factor;
if (deltaCoef > newResult) {
hasResult = true;
break
}
result = newResult
}
}
return utils.adjustValue(result)
},
_getLogarithmicTickInterval: function(deltaCoef, numberMultipliers) {
var result = 0;
if (deltaCoef !== 0)
result = this._getCommonTickInterval(deltaCoef, numberMultipliers);
return utils.adjustValue(result)
},
_getDateTimeTickInterval: function(deltaCoef, numberMultipliers) {
var dateTimeMultipliers = {
millisecond: [1, 2, 5, 10, 25, 100, 250, 300, 500],
second: [1, 2, 3, 5, 10, 15, 20, 30],
minute: [1, 2, 3, 5, 10, 15, 20, 30],
hour: [1, 2, 3, 4, 6, 8, 12],
day: [1, 2, 3, 5, 7, 10, 14],
month: [1, 2, 3, 6]
},
result = {},
factor,
key,
specificMultipliers,
yearsCount,
i;
if (deltaCoef > 0 && deltaCoef < 1.0)
return {milliseconds: 1};
else if (deltaCoef === 0)
return 0;
for (key in dateTimeMultipliers)
if (dateTimeMultipliers.hasOwnProperty(key)) {
specificMultipliers = dateTimeMultipliers[key];
for (i = 0; i < specificMultipliers.length; i++)
if (deltaCoef <= utils.convertDateUnitToMilliseconds(key, specificMultipliers[i])) {
result[key + 's'] = specificMultipliers[i];
return result
}
}
for (factor = 1; ; factor *= 10)
for (i = 0; i < numberMultipliers.length; i++) {
yearsCount = factor * numberMultipliers[i];
if (deltaCoef <= utils.convertDateUnitToMilliseconds('year', yearsCount))
return {years: yearsCount}
}
return null
},
getTickInterval: function(options) {
var that = this,
gridSpacingFactor = options.gridSpacingFactor || that._defaultGridSpacingFactor,
numberMultipliers = options.numberMultipliers || that._defaultNumberMultipliers,
businessDelta = options.businessDelta,
screenDelta = options.screenDelta,
deltaCoef = screenDelta > 0 && gridSpacingFactor < screenDelta ? gridSpacingFactor * businessDelta / screenDelta : 0;
that._testNumberMultipliers = numberMultipliers;
if (options.axisType === 'logarithmic')
return that._getLogarithmicTickInterval(deltaCoef, numberMultipliers);
else
switch (options.dataType) {
case'numeric':
return that._getNumericTickInterval(deltaCoef, numberMultipliers);
break;
case'datetime':
return that._getDateTimeTickInterval(deltaCoef, numberMultipliers);
break
}
return null
}
};
core.minorTickIntervalCalculator = {
_defaultNumberMultipliers: [2, 4, 5, 8, 10],
_defaultGridSpacingFactor: 15,
_getDateTimeTickInterval: function(businessDelta, deltaCoef, numberMultipliers) {
var result,
i;
for (i = numberMultipliers.length - 1; i >= 0; i--) {
this.testResultNumberMultiplier = numberMultipliers[i];
result = mathFloor(businessDelta / numberMultipliers[i]);
if (deltaCoef <= result)
return utils.convertMillisecondsToDateUnits(result)
}
return 0
},
_getCommonTickInterval: function(businessDelta, deltaCoef, numberMultipliers) {
var result,
i;
for (i = numberMultipliers.length - 1; i >= 0; i--) {
this.testResultNumberMultiplier = numberMultipliers[i];
result = businessDelta / numberMultipliers[i];
if (deltaCoef <= result)
return utils.adjustValue(result)
}
return 0
},
getTickInterval: function(options) {
var that = this,
gridSpacingFactor = !utils.isDefined(options.gridSpacingFactor) ? that._defaultGridSpacingFactor : options.gridSpacingFactor,
numberMultipliers = options.numberMultipliers || that._defaultNumberMultipliers,
businessDelta = options.businessDelta,
deltaCoef = gridSpacingFactor * businessDelta / options.screenDelta;
if (options.axisType === 'logarithmic')
return that._getCommonTickInterval(businessDelta, deltaCoef, numberMultipliers);
else
switch (options.dataType) {
case'numeric':
return that._getCommonTickInterval(businessDelta, deltaCoef, numberMultipliers);
case'datetime':
return that._getDateTimeTickInterval(businessDelta, deltaCoef, numberMultipliers)
}
return 0
}
};
core.tickProvider = {
_appendFakeSVGElement: function(value, text, options) {
var textOptions = $.extend({}, options.textOptions, {rotate: 0});
return options.renderer.createText(text, core.outOfScreen.x + (options.translator.translate(value) || 0), core.outOfScreen.y, textOptions).append()
},
_getDistanceByAngle: function(elementHeight, rotationAngle) {
return elementHeight / mathAbs(math.sin(rotationAngle * (math.PI / 180)))
},
_areDisplayValuesValid: function(value1, value2, options) {
var that = this,
getText = that._getTextFunc(options),
rotationAngle = options.textOptions && utils.isNumber(options.textOptions.rotate) ? options.textOptions.rotate : 0,
svgElement1 = that._appendFakeSVGElement(value1, getText(value1), options),
svgElement2 = that._appendFakeSVGElement(value2, getText(value2), options),
bBox1 = svgElement1.getBBox(),
bBox2 = svgElement2.getBBox(),
result,
translator = options.translator;
if (rotationAngle !== 0)
result = that._getDistanceByAngle(bBox1.height, rotationAngle) <= mathAbs(bBox2.x - bBox1.x);
else if (options.isHorizontal)
result = !translator.getBusinessRange().invert ? bBox1.x + bBox1.width < bBox2.x : bBox2.x + bBox2.width < bBox1.x;
else
result = mathAbs(translator.translate(value1) - translator.translate(value2)) > bBox1.height;
svgElement1.remove();
svgElement2.remove();
return result
},
_removeInvalidDatesWithUnitBegining: function(dates, options) {
if (dates.length <= 1 || !options.setTicksAtUnitBeginning || !utils.isDate(options.min))
return;
if (!this._areDisplayValuesValid(dates[0], dates[1], options))
dates.splice(1, 1)
},
_getValueSize: function(values, options) {
var that = this,
value,
rotationAngle = options.textOptions ? options.textOptions.rotate : 0,
svgElement,
bBox,
result,
getText = that._getTextFunc(options),
i;
if (values.length === 0)
return 0;
options.isRotate = utils.isNumber(rotationAngle) && rotationAngle !== 0;
if (options.isRotate || !options.isHorizontal)
value = getText(values[0]);
else {
value = [];
for (i = 0; i < values.length; i++)
value.push(getText(values[i]));
value = value.join('\n')
}
svgElement = that._appendFakeSVGElement(value, value, options);
bBox = svgElement.getBBox();
if (options.isRotate)
result = that._getDistanceByAngle(bBox.height, rotationAngle);
else
result = options.isHorizontal ? bBox.width : bBox.height;
svgElement.remove();
return mathCeil(result)
},
_adjustNumericTickValue: function(value, interval, min) {
return utils.isExponential(value) ? utils.adjustValue(value) : utils.applyPrecisionByMinDelta(min, interval, value)
},
_generateStartTick: function(tickInterval, options) {
var that = this,
milliseconds = 0,
boundedRule = options.min - options.max < 0,
startTick = options.min,
isDate = utils.isDate(options.min),
currentTickInterval = isDate ? utils.convertDateTickIntervalToMilliseconds(tickInterval) : tickInterval,
nextTick;
if (options.axisType === 'logarithmic')
startTick = utils.raiseTo(mathFloor(utils.adjustValue(utils.getLog(options.min, options.base)) / currentTickInterval * currentTickInterval), options.base);
else {
startTick = mathFloor(options.min / currentTickInterval) * currentTickInterval;
startTick = isDate ? new Date(startTick) : that._adjustNumericTickValue(startTick, currentTickInterval, options.min)
}
while (boundedRule === startTick - options.min < 0 && startTick !== options.min) {
nextTick = that._nextTick(startTick, tickInterval, options);
if (nextTick !== startTick)
startTick = nextTick;
else
return nextTick
}
return startTick
},
_nextTick: function(tick, tickInterval, options) {
var nextTick,
lgPower,
that = this;
if (options.axisType === 'logarithmic') {
lgPower = utils.addInterval(utils.adjustValue(utils.getLog(tick, options.base)), tickInterval, options.min > options.max);
nextTick = utils.raiseTo(lgPower, options.base);
nextTick = that._adjustNumericTickValue(nextTick, tickInterval, math.min(options.min, options.max))
}
else {
nextTick = utils.addInterval(tick, tickInterval, options.min > options.max);
if (options.dataType === 'numeric')
nextTick = that._adjustNumericTickValue(nextTick, tickInterval, options.min);
if (options.dataType === 'datetime' && options.setTicksAtUnitBeginning)
utils.correctDateWithUnitBeginning(nextTick, tickInterval)
}
return nextTick
},
_addMinorTicks: function(majorTick1, majorTick2, ticksInfo, options, isReverse) {
var that = this,
i,
dataType = options.dataType,
businessDelta,
minorTicks = [],
interval = 0,
minorTickIntervalsCount = options.minorTickCount + 1,
intervalsCount,
tickInterval;
options.min = majorTick1;
options.max = majorTick2;
if (!utils.isDefined(options.tickInterval)) {
options.businessDelta = businessDelta = mathAbs(options.max - options.min);
options.screenDelta = businessDelta * options.deltaCoef;
if (utils.isDefined(options.minorTickCount)) {
if (!ticksInfo.majorTicks.autoArrangementStep || ticksInfo.majorTicks.autoArrangementStep <= 1) {
intervalsCount = options.minorTickCount + 1;
interval = dataType === 'datetime' ? utils.convertDateTickIntervalToMilliseconds(ticksInfo.majorTickInterval) : ticksInfo.majorTickInterval;
minorTickIntervalsCount = mathRound(businessDelta / interval * intervalsCount) || 1
}
tickInterval = dataType === 'datetime' ? utils.convertMillisecondsToDateUnits(businessDelta / minorTickIntervalsCount) : businessDelta / minorTickIntervalsCount;
if ($.isNumeric(tickInterval))
tickInterval = utils.adjustValue(tickInterval)
}
else if (utils.isDate(majorTick1))
tickInterval = core.minorTickIntervalCalculator.getTickInterval(options)
}
options = $.extend(true, {}, options, {tickInterval: tickInterval});
minorTicks = that.getTicks(options);
if (isReverse)
minorTicks.reverse();
if (minorTicks.length > 0)
if (mathCeil(mathAbs(majorTick2 - minorTicks[minorTicks.length - 1]) * options.deltaCoef) < 2)
minorTicks.pop();
for (i = 0; i < minorTicks.length; i++) {
ticksInfo.minorTicks.push(minorTicks[i]);
ticksInfo.fullTicks.push(minorTicks[i])
}
},
_addLeftBoudedTicks: function(ticksInfo, min, minorTicksOptions) {
if (utils.isDefined(min) && ticksInfo.majorTicks[0].valueOf() !== min.valueOf()) {
minorTicksOptions.addMinMax.max = true;
this._addMinorTicks(ticksInfo.majorTicks[0], min, ticksInfo, minorTicksOptions, true);
minorTicksOptions.addMinMax.max = false;
if (minorTicksOptions.showCustomBoundaryTicks) {
if (ticksInfo.minorTicks.length > 0 && ticksInfo.minorTicks[0].valueOf() === min.valueOf())
ticksInfo.minorTicks.shift(min);
ticksInfo.customBoundaryTicks.push(min);
ticksInfo.fullTicks.unshift(min)
}
}
},
_addRightBoudedTicks: function(ticksInfo, max, minorTicksOptions) {
var lastMajorTick = ticksInfo.majorTicks[ticksInfo.majorTicks.length - 1];
ticksInfo.fullTicks.push(lastMajorTick);
if (utils.isDefined(max) && lastMajorTick.valueOf() !== max.valueOf()) {
minorTicksOptions.addMinMax.min = false;
minorTicksOptions.addMinMax.max = true;
this._addMinorTicks(lastMajorTick, max, ticksInfo, minorTicksOptions);
if (minorTicksOptions.showCustomBoundaryTicks) {
if (ticksInfo.minorTicks.length > 0 && ticksInfo.minorTicks[ticksInfo.minorTicks.length - 1].valueOf() === max.valueOf())
ticksInfo.minorTicks.pop(max);
ticksInfo.customBoundaryTicks.push(max);
ticksInfo.fullTicks.push(max)
}
}
},
_correctBoundedTicks: function(min, max, ticks, addMinMax) {
addMinMax = $.extend({}, {
min: true,
max: true
}, addMinMax);
if (ticks.length > 0) {
if (!addMinMax.min && ticks[0].valueOf() === min.valueOf())
ticks.shift();
if (!addMinMax.max || ticks[ticks.length - 1].valueOf() !== max.valueOf())
ticks.pop()
}
},
_initializeMinorTicksOptions: function(min, max, screenDelta, ticksInfo, options) {
var that = this,
businessDelta,
hasMinorsCount = utils.isDefined(options.minorTickCount);
$.extend(true, options, {
addMinMax: {
min: false,
max: false
},
deltaCoef: that._getDeltaCoef(screenDelta, max, min, options.axisType, options.base)
}, options);
options.numberMultipliers = hasMinorsCount ? [options.minorTickCount + 1] : options.numberMultipliers;
options.gridSpacingFactor = hasMinorsCount ? 0 : options.gridSpacingFactor;
if (!hasMinorsCount && ticksInfo.majorTicks.length > 1) {
options.businessDelta = businessDelta = that._getBusinessDelta(options.axisType, ticksInfo.majorTicks[0], ticksInfo.majorTicks[1], options.base);
if (that.needTickIntervalCalculation(businessDelta, ticksInfo.minorTickInterval, options.incidentOccured)) {
options.screenDelta = businessDelta * options.deltaCoef;
ticksInfo.minorTickInterval = core.minorTickIntervalCalculator.getTickInterval(options);
if (utils.isNumber(min))
options.tickInterval = ticksInfo.minorTickInterval;
else
options.tickInterval = undefined
}
}
},
_getDataType: function(value) {
return utils.isDate(value) ? 'datetime' : 'numeric'
},
_getBusinessDelta: function(type, min, max, base) {
return type === 'logarithmic' ? mathRound(mathAbs(utils.getLog(min, base) - utils.getLog(max, base))) : mathAbs(min - max)
},
_getDeltaCoef: function(screenDelta, max, min, type, base) {
return screenDelta / this._getBusinessDelta(type, min, max, base)
},
_initializeMajorTicksOptions: function(min, max, screenDelta, ticksInfo, options) {
var businessDelta;
options.screenDelta = screenDelta;
$.extend(true, options, {
min: min,
max: max,
screenDelta: screenDelta,
isHorizontal: true
});
if (utils.isDefined(min) && utils.isDefined(max)) {
options.businessDelta = businessDelta = this._getBusinessDelta(options.axisType, min, max, options.base);
if (this.needTickIntervalCalculation(businessDelta, ticksInfo.majorTickInterval, options.incidentOccured)) {
options.isStartTickGenerated = true;
ticksInfo.majorTickInterval = core.tickIntervalCalculator.getTickInterval(options);
options.tickInterval = ticksInfo.majorTickInterval
}
}
},
_getTextFunc: function(options) {
return options.getText || function(value) {
return value.toString()
}
},
_generateTicks: function(options) {
var that = this,
ticks = [],
tick,
boundedRule = options.max - options.min > 0,
leftBound,
rightBound,
tickInterval,
isStartTickGenerated = options.isStartTickGenerated,
businessDelta,
useTicksAutoArrangement = options.useTicksAutoArrangement;
options.dataType = options.dataType || that._getDataType(options.min);
options.businessDelta = businessDelta = that._getBusinessDelta(options.axisType, options.min, options.max, options.base);
if (!utils.isDefined(options.min) || !utils.isDefined(options.max) || isNaN(options.min) || isNaN(options.max)) {
ticks = options.isHorizontal ? ['canvas_position_left', 'canvas_position_center', 'canvas_position_right'] : ['canvas_position_bottom', 'canvas_position_middle', 'canvas_position_top'];
useTicksAutoArrangement = false;
ticks.hideLabels = true
}
else {
tickInterval = $.isNumeric(options.min) && $.isNumeric(options.max) && !$.isNumeric(options.tickInterval) ? undefined : options.tickInterval;
if (this.needTickIntervalCalculation(businessDelta, tickInterval, options.incidentOccured)) {
isStartTickGenerated = utils.isDefined(isStartTickGenerated) ? isStartTickGenerated : true;
tickInterval = core.tickIntervalCalculator.getTickInterval(options)
}
ticks.tickInterval = tickInterval;
that.isTestStartTickGenerated = isStartTickGenerated;
that.isTestTickInterval = tickInterval;
that.testGridSpacingFactor = options.gridSpacingFactor;
if (tickInterval && tickInterval.valueOf() !== 0 && options.min.valueOf() !== options.max.valueOf()) {
tick = isStartTickGenerated ? that._generateStartTick(tickInterval, options) : options.min;
do {
ticks.push(tick);
tick = that._nextTick(tick, tickInterval, options);
if (ticks[ticks.length - 1].valueOf() === tick.valueOf())
break;
leftBound = tick - options.min > 0;
rightBound = options.max - tick > 0
} while (boundedRule === leftBound && boundedRule === rightBound);
ticks.push(tick);
that._correctBoundedTicks(options.min, options.max, ticks, options.addMinMax)
}
if (options.min.valueOf() === options.max.valueOf()) {
tick = options.min;
ticks.push(tick)
}
}
return ticks
},
_getAutoArrangementStep: function(ticks, options) {
var that = this,
requiredValuesCount,
addedSpacing = options.isHorizontal ? options.textSpacing : 0;
if (options.getCustomAutoArrangementStep)
return options.getCustomAutoArrangementStep(ticks, options);
if (options.maxDisplayValueSize > 0) {
requiredValuesCount = mathFloor((options.screenDelta + options.textSpacing) / (options.maxDisplayValueSize + addedSpacing));
return mathCeil((options.ticksCount || ticks.length) / requiredValuesCount)
}
return 1
},
_getAutoArrangementTicks: function(ticks, options, step) {
var that = this,
resultTicks = ticks,
i;
if (step > 1) {
resultTicks = [];
for (i = 0; i < ticks.length; i += step)
resultTicks.push(ticks[i]);
resultTicks.tickInterval = ticks.tickInterval * step
}
return resultTicks
},
isOverlappedTicks: function(ticks, options) {
options.maxDisplayValueSize = this._getValueSize(ticks, options);
return this._getAutoArrangementStep(ticks, options) > 1
},
getCorrectedTicks: function(ticks, ticksOptions) {
var step = Math.ceil(core.tickIntervalCalculator.getTickInterval({
screenDelta: ticksOptions.screenDelta * 4,
businessDelta: ticks.length,
gridSpacingFactor: ticksOptions.gridSpacingFactor,
numberMultipliers: ticksOptions.numberMultipliers,
dataType: "numeric"
})) || ticks.length;
return this._getAutoArrangementTicks(ticks, ticksOptions, step)
},
needTickIntervalCalculation: function(businessDelta, tickInterval, incidentOccured) {
var date;
if (utils.isDefined(tickInterval)) {
if (!utils.isNumber(tickInterval)) {
date = new Date;
tickInterval = utils.addInterval(date, tickInterval) - date;
if (!tickInterval)
return true
}
if (utils.isNumber(tickInterval))
if (tickInterval > 0 && businessDelta / tickInterval > TICKS_COUNT_LIMIT) {
if (incidentOccured)
incidentOccured('W2003')
}
else
return false
}
return true
},
getTickIntervals: function(min, max, screenDelta, majorTicksOptions, minorTicksOptions, options) {
var that = this,
i,
options = options || {},
ticksInfo = {
majorTickInterval: majorTicksOptions.tickInterval,
minorTickInterval: minorTicksOptions.tickInterval,
majorTicks: []
};
majorTicksOptions.base = minorTicksOptions.base = options.base;
majorTicksOptions.axisType = minorTicksOptions.axisType = options.axisType;
majorTicksOptions.dataType = minorTicksOptions.dataType = options.dataType;
that._initializeMajorTicksOptions(min, max, screenDelta, ticksInfo, majorTicksOptions);
if (utils.isDefined(min) && utils.isDefined(max)) {
ticksInfo.majorTicks.push(min);
ticksInfo.majorTicks.push(that._nextTick(min, ticksInfo.majorTickInterval, {
min: min,
max: max,
setTicksAtUnitBeginning: majorTicksOptions.setTicksAtUnitBeginning,
dataType: options.dataType,
axisType: options.axisType,
base: options.base
}));
that._initializeMinorTicksOptions(min, max, screenDelta, ticksInfo, minorTicksOptions)
}
return ticksInfo
},
getFullTicks: function(min, max, screenDelta, majorTicksOptions, minorTicksOptions, options) {
var that = this,
i,
options = options || {},
ticksInfo = {
customBoundaryTicks: [],
fullTicks: [],
majorTickInterval: majorTicksOptions.tickInterval,
majorTicks: [],
minorTickInterval: minorTicksOptions.tickInterval,
minorTicks: []
};
majorTicksOptions.base = minorTicksOptions.base = options.base;
majorTicksOptions.axisType = minorTicksOptions.axisType = options.axisType;
majorTicksOptions.dataType = minorTicksOptions.dataType = options.dataType || that._getDataType(min);
that._initializeMajorTicksOptions(min, max, screenDelta, ticksInfo, majorTicksOptions);
ticksInfo.majorTicks = that.getTicks(majorTicksOptions);
if (utils.isDefined(min) && utils.isDefined(max) && ticksInfo.majorTicks.length > 0) {
if (ticksInfo.majorTicks.autoArrangementStep && ticksInfo.majorTicks.autoArrangementStep > 1 && !utils.isDefined(minorTicksOptions.tickInterval) && !utils.isDefined(minorTicksOptions.minorTickCount))
minorTicksOptions.tickInterval = ticksInfo.minorTickInterval = majorTicksOptions.tickInterval;
that._initializeMinorTicksOptions(min, max, screenDelta, ticksInfo, minorTicksOptions);
that._addLeftBoudedTicks(ticksInfo, min, minorTicksOptions);
for (i = 0; i < ticksInfo.majorTicks.length - 1; i++) {
ticksInfo.fullTicks.push(ticksInfo.majorTicks[i]);
that._addMinorTicks(ticksInfo.majorTicks[i], ticksInfo.majorTicks[i + 1], ticksInfo, minorTicksOptions)
}
that._addRightBoudedTicks(ticksInfo, max, minorTicksOptions)
}
return ticksInfo
},
getTicks: function(options) {
var that = this,
step,
maxDisplayValue,
ticks = options.customTicks ? options.customTicks : that._generateTicks(options);
if (options.useTicksAutoArrangement) {
options.maxDisplayValueSize = that._getValueSize(ticks, options);
step = that._getAutoArrangementStep(ticks, options);
if (step > 1) {
if (utils.isDefined(options.tickInterval) || utils.isDefined(options.customTicks)) {
utils.isDefined(options.customTicks) && (ticks.tickInterval = options.tickInterval);
ticks = that._getAutoArrangementTicks(ticks, options, step)
}
else
ticks = that._generateTicks($.extend({}, options, {gridSpacingFactor: options.maxDisplayValueSize}));
ticks.autoArrangementStep = step
}
that._removeInvalidDatesWithUnitBegining(ticks, options)
}
return ticks
}
}
})(jQuery, DevExpress);
/*! Module viz-core, file numericTranslator.js */
(function($, DX, undefined) {
var utils = DX.utils,
isDefined = utils.isDefined,
getPower = utils.getPower,
round = Math.round;
DX.viz.core.numericTranslatorFunctions = {
translate: function(bp) {
var that = this,
canvasOptions = that._canvasOptions,
doubleError = canvasOptions.rangeDoubleError,
specialValue = that.translateSpecialCase(bp);
if (isDefined(specialValue))
return specialValue;
if (isNaN(bp) || bp.valueOf() + doubleError < canvasOptions.rangeMin || bp.valueOf() - doubleError > canvasOptions.rangeMax)
return null;
return round(that._calculateProjection((bp - canvasOptions.rangeMinVisible) * canvasOptions.ratioOfCanvasRange))
},
untranslate: function(pos) {
var canvasOptions = this._canvasOptions,
startPoint = canvasOptions.startPoint;
if (pos < startPoint || pos > canvasOptions.endPoint)
return null;
return this._calculateUnProjection((pos - startPoint) / canvasOptions.ratioOfCanvasRange)
},
getInterval: function() {
return round(this._canvasOptions.ratioOfCanvasRange * (this._businessRange.interval || Math.abs(this._canvasOptions.rangeMax - this._canvasOptions.rangeMin)))
}
}
})(jQuery, DevExpress);
/*! Module viz-core, file datetimeTranslator.js */
(function($, DX, undefined) {
var core = DX.viz.core,
numericTranslator = core.numericTranslatorFunctions;
core.datetimeTranslatorFunctions = {
translate: numericTranslator.translate,
untranslate: function(pos) {
var result = numericTranslator.untranslate.call(this, pos);
return result === null ? result : new Date(result)
},
getInterval: numericTranslator.getInterval
}
})(jQuery, DevExpress);
/*! Module viz-core, file categoryTranslator.js */
(function($, DX, undefined) {
var isDefined = DX.utils.isDefined,
round = Math.round;
function doubleRound(value) {
return round(round(value * 10) / 10)
}
DX.viz.core.categoryTranslatorFunctions = {
translate: function(category) {
var that = this,
canvasOptions = that._canvasOptions,
categoryRecord = that._categoriesToPoints[category],
stickDelta,
specialValue = that.translateSpecialCase(category);
if (isDefined(specialValue))
return specialValue;
if (!categoryRecord)
return 0;
stickDelta = that._businessRange.stick ? categoryRecord.index : categoryRecord.index + 0.5;
return round(canvasOptions.startPoint + canvasOptions.interval * stickDelta)
},
untranslate: function(pos) {
var that = this,
canvasOptions = that._canvasOptions,
startPoint = canvasOptions.startPoint,
categoriesLength = that._categories.length,
result = 0;
if (pos < startPoint || pos > canvasOptions.endPoint)
return null;
result = doubleRound((pos - startPoint) / canvasOptions.interval + (that._businessRange.stick ? 0.5 : 0) - 0.5);
if (categoriesLength === result)
result--;
if (canvasOptions.invert)
result = categoriesLength - result - 1;
return that._categories[result]
},
getInterval: function() {
return this._canvasOptions.interval
}
}
})(jQuery, DevExpress);
/*! Module viz-core, file logarithmicTranslator.js */
(function($, DX, undefined) {
var core = DX.viz.core,
numericTranslator = core.numericTranslatorFunctions,
utils = DX.utils,
raiseTo = utils.raiseTo,
getLog = utils.getLog;
core.logarithmicTranslatorFunctions = {
translate: function(bp) {
var that = this,
specialValue = that.translateSpecialCase(bp);
if (utils.isDefined(specialValue))
return specialValue;
return numericTranslator.translate.call(that, getLog(bp, that._businessRange.base))
},
untranslate: function(pos) {
var result = numericTranslator.untranslate.call(this, pos);
return result === null ? result : raiseTo(result, this._businessRange.base)
},
getInterval: numericTranslator.getInterval
}
})(jQuery, DevExpress);
/*! Module viz-core, file translator1D.js */
(function(DX, undefined) {
var _Number = Number;
function Translator1D() {
this.setDomain(arguments[0], arguments[1]).setCodomain(arguments[2], arguments[3])
}
Translator1D.prototype = {
constructor: Translator1D,
setDomain: function(domain1, domain2) {
var that = this;
that._domain1 = _Number(domain1);
that._domain2 = _Number(domain2);
that._domainDelta = that._domain2 - that._domain1;
return that
},
setCodomain: function(codomain1, codomain2) {
var that = this;
that._codomain1 = _Number(codomain1);
that._codomain2 = _Number(codomain2);
that._codomainDelta = that._codomain2 - that._codomain1;
return that
},
getDomain: function() {
return [this._domain1, this._domain2]
},
getCodomain: function() {
return [this._codomain1, this._codomain2]
},
getDomainStart: function() {
return this._domain1
},
getDomainEnd: function() {
return this._domain2
},
getCodomainStart: function() {
return this._codomain1
},
getCodomainEnd: function() {
return this._codomain2
},
getDomainRange: function() {
return this._domainDelta
},
getCodomainRange: function() {
return this._codomainDelta
},
translate: function(value) {
var ratio = (_Number(value) - this._domain1) / this._domainDelta;
return 0 <= ratio && ratio <= 1 ? this._codomain1 + ratio * this._codomainDelta : NaN
},
adjust: function(value) {
var ratio = (_Number(value) - this._domain1) / this._domainDelta,
result = NaN;
if (ratio < 0)
result = this._domain1;
else if (ratio > 1)
result = this._domain2;
else if (0 <= ratio && ratio <= 1)
result = _Number(value);
return result
}
};
DX.viz.core.Translator1D = Translator1D
})(DevExpress);
/*! Module viz-core, file translator2D.js */
(function($, DX, undefined) {
var core = DX.viz.core,
utils = DX.utils,
getLog = utils.getLog,
getPower = utils.getPower,
raiseTo = utils.raiseTo,
isDefined = utils.isDefined,
CANVAS_PROP = ["width", "height", "left", "top", "bottom", "right"],
NUMBER_EQUALITY_CORRECTION = 1,
DATETIME_EQUALITY_CORRECTION = 60000;
var validateCanvas = function(canvas) {
$.each(CANVAS_PROP, function(_, prop) {
canvas[prop] = parseInt(canvas[prop]) || 0
});
return canvas
};
var raiseToFlooredLog = function(value, base, correction) {
return raiseTo(Math.floor(getLog(value, base)) + (correction || 0), base)
};
var makeCategoriesToPoints = function(categories, invert) {
var categoriesToPoints = {},
category,
length = categories.length,
i;
for (i = 0; i < length; i++) {
category = categories[i];
categoriesToPoints[category] = {
name: category,
index: invert ? length - 1 - i : i
}
}
return categoriesToPoints
};
var validateBusinessRange = function(businessRange) {
function validate(valueSelector, baseValueSeletor) {
if (!isDefined(businessRange[valueSelector]) && isDefined(businessRange[baseValueSeletor]))
businessRange[valueSelector] = businessRange[baseValueSeletor]
}
validate("minVisible", "min");
validate("maxVisible", "max");
return businessRange
};
core.Translator2D = function(businessRange, canvas, options) {
var that = this;
that._options = $.extend(that._options || {}, options);
that._canvas = validateCanvas(canvas);
that.updateBusinessRange(businessRange)
};
$.extend(core.Translator2D.prototype, {
reinit: function() {
var that = this,
range = that._businessRange,
categories = range.categories || [],
script = {},
canvasOptions = that._prepareCanvasOptions(),
interval,
correctedCategoriesCount;
switch (range.axisType) {
case"logarithmic":
script = core.logarithmicTranslatorFunctions;
break;
case"discrete":
script = core.categoryTranslatorFunctions;
that._categories = categories;
correctedCategoriesCount = categories.length - (range.stick ? 1 : 0);
if (correctedCategoriesCount > 0)
interval = canvasOptions.canvasLength / correctedCategoriesCount;
else
interval = canvasOptions.canvasLength;
canvasOptions.interval = interval;
that._categoriesToPoints = makeCategoriesToPoints(categories, canvasOptions.invert);
break;
default:
if (range.dataType === "datetime")
script = core.datetimeTranslatorFunctions;
else
script = core.numericTranslatorFunctions
}
that.translate = script.translate;
that.untranslate = script.untranslate;
that.getInterval = script.getInterval
},
_getCanvasBounds: function(range) {
var min = range.min,
max = range.max,
minVisible = range.minVisible,
maxVisible = range.maxVisible,
newMin,
newMax,
base = range.base,
isDateTime = utils.isDate(max) || utils.isDate(min),
correction = isDateTime ? DATETIME_EQUALITY_CORRECTION : NUMBER_EQUALITY_CORRECTION;
if (isDefined(min) && isDefined(max) && min.valueOf() === max.valueOf()) {
newMin = min.valueOf() - correction;
newMax = max.valueOf() + correction;
if (isDateTime) {
min = new Date(newMin);
max = new Date(newMax)
}
else {
min = min !== 0 ? newMin : 0;
max = newMax
}
}
if (isDefined(minVisible) && isDefined(maxVisible) && minVisible.valueOf() === maxVisible.valueOf()) {
newMin = minVisible.valueOf() - correction;
newMax = maxVisible.valueOf() + correction;
if (isDateTime) {
minVisible = newMin < min.valueOf() ? min : new Date(newMin);
maxVisible = newMax > max.valueOf() ? max : new Date(newMax)
}
else {
if (minVisible !== 0)
minVisible = newMin < min ? min : newMin;
maxVisible = newMax > max ? max : newMax
}
}
if (range.axisType === 'logarithmic') {
maxVisible = getLog(maxVisible, base);
minVisible = getLog(minVisible, base);
min = getLog(min, base);
max = getLog(max, base)
}
return {
base: base,
rangeMin: min,
rangeMax: max,
rangeMinVisible: minVisible,
rangeMaxVisible: maxVisible
}
},
_prepareCanvasOptions: function() {
var that = this,
rangeMin,
rangeMax,
rangeMinVisible,
rangeMaxVisible,
businessRange = that._businessRange,
canvasOptions = that._canvasOptions = that._getCanvasBounds(businessRange),
length;
if (that._options.direction === "horizontal") {
canvasOptions.startPoint = that._canvas.left;
length = that._canvas.width;
canvasOptions.endPoint = that._canvas.width - that._canvas.right;
canvasOptions.invert = businessRange.invert
}
else {
canvasOptions.startPoint = that._canvas.top;
length = that._canvas.height;
canvasOptions.endPoint = that._canvas.height - that._canvas.bottom;
canvasOptions.invert = !businessRange.invert
}
that.canvasLength = canvasOptions.canvasLength = canvasOptions.endPoint - canvasOptions.startPoint;
canvasOptions.rangeDoubleError = Math.pow(10, getPower(canvasOptions.rangeMax - canvasOptions.rangeMin) - getPower(length) - 2);
canvasOptions.ratioOfCanvasRange = canvasOptions.canvasLength / (canvasOptions.rangeMaxVisible - canvasOptions.rangeMinVisible);
return canvasOptions
},
updateBusinessRange: function(businessRange) {
this._businessRange = validateBusinessRange(businessRange);
this.reinit()
},
getBusinessRange: function() {
return this._businessRange
},
getCanvasVisibleArea: function() {
return {
min: this._canvasOptions.startPoint,
max: this._canvasOptions.endPoint
}
},
translateSpecialCase: function(value) {
var that = this,
canvasOptions = that._canvasOptions,
startPoint = canvasOptions.startPoint,
endPoint = canvasOptions.endPoint,
range = that._businessRange,
minVisible = range.minVisible,
maxVisible = range.maxVisible,
invert,
result = null;
switch (value) {
case"canvas_position_default":
if (minVisible <= 0 && maxVisible >= 0)
result = that.translate(0);
else {
invert = range.invert ^ (minVisible <= 0 && maxVisible <= 0);
if (that._options.direction === "horizontal")
result = invert ? endPoint : startPoint;
else
result = invert ? startPoint : endPoint
}
break;
case"canvas_position_left":
case"canvas_position_top":
result = startPoint;
break;
case"canvas_position_center":
case"canvas_position_middle":
result = startPoint + canvasOptions.canvasLength / 2;
break;
case"canvas_position_right":
case"canvas_position_bottom":
result = endPoint;
break;
case"canvas_position_start":
result = range.invert ? endPoint : startPoint;
break;
case"canvas_position_end":
result = range.invert ? startPoint : endPoint;
break
}
return result
},
_calculateProjection: function(distance) {
var canvasOptions = this._canvasOptions;
return canvasOptions.invert ? canvasOptions.endPoint - distance : canvasOptions.startPoint + distance
},
_calculateUnProjection: function(distance) {
var canvasOptions = this._canvasOptions;
return canvasOptions.invert ? canvasOptions.rangeMaxVisible.valueOf() - distance : canvasOptions.rangeMinVisible.valueOf() + distance
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file rectangle.js */
(function(DX, undefined) {
var isFinite = window.isFinite;
DX.viz.core.Rectangle = DX.Class.inherit({
ctor: function(options) {
var that = this;
options = options || {};
that.left = Number(options.left) || 0;
that.right = Number(options.right) || 0;
that.top = Number(options.top) || 0;
that.bottom = Number(options.bottom) || 0
},
width: function() {
return this.right - this.left
},
height: function() {
return this.bottom - this.top
},
horizontalMiddle: function() {
return (this.left + this.right) / 2
},
verticalMiddle: function() {
return (this.top + this.bottom) / 2
},
raw: function() {
var that = this;
return {
left: that.left,
top: that.top,
right: that.right,
bottom: that.bottom
}
},
clone: function() {
return new this.constructor(this.raw())
},
move: function(dx, dy) {
var result = this.clone();
if (isFinite(dx) && isFinite(dy)) {
result.left += Number(dx);
result.right += Number(dx);
result.top += Number(dy);
result.bottom += Number(dy)
}
return result
},
inflate: function(dx, dy) {
var result = this.clone();
if (isFinite(dx) && isFinite(dy)) {
result.left -= Number(dx);
result.right += Number(dx);
result.top -= Number(dy);
result.bottom += Number(dy)
}
return result
},
scale: function(factor) {
var that = this;
if (factor > 0)
return that.inflate(that.width() * (factor - 1) / 2, that.height() * (factor - 1) / 2);
return that.clone()
}
})
})(DevExpress);
/*! Module viz-core, file themes.js */
(function($, DX, undefined) {
var viz = DX.viz,
core = viz.core;
var currentThemeId = 0;
var findThemeId = function(themeName) {
var themeId,
themes = viz.themes;
for (themeId = 0; themeId < themes.length; themeId++)
if (themes[themeId].name === themeName)
return themeId;
return -1
};
core.findTheme = function(themeName) {
var themeId = findThemeId(themeName),
themes = viz.themes;
if (themeId < 0)
themeId = currentThemeId;
return themes[themeId]
};
core.currentTheme = function(themeName, colorScheme, version) {
var themeId = -1,
themes = viz.themes;
if (themeName === undefined)
return themes[currentThemeId].name;
else {
if (version && colorScheme)
themeId = findThemeId(themeName + ':' + version + '-' + colorScheme);
if (themeId < 0 && version)
themeId = findThemeId(themeName + ':' + version);
if (colorScheme && themeId < 0)
themeId = findThemeId(themeName + '-' + colorScheme);
if (themeId < 0)
themeId = findThemeId(themeName);
currentThemeId = themeId >= 0 ? themeId : 0
}
};
core.registerTheme = function(theme, basedOnThemeName) {
var baseTheme,
extendedTheme,
themes = viz.themes;
if (!theme || !theme.name || !core.findTheme(theme.name))
return;
baseTheme = core.findTheme(basedOnThemeName);
if (baseTheme) {
extendedTheme = $.extend(true, {}, baseTheme, theme);
themes.push(extendedTheme)
}
else
themes.push(theme)
}
})(jQuery, DevExpress);
/*! Module viz-core, file palette.js */
(function(DX, $, undefined) {
var _String = window.String,
_Color = DX.Color,
_isArray = DX.utils.isArray,
_isString = DX.utils.isString,
_extend = $.extend;
var palettes = {
'default': {
simpleSet: ['#5f8b95', '#ba4d51', '#af8a53', '#955f71', '#859666', '#7e688c'],
indicatingSet: ['#a3b97c', '#e1b676', '#ec7f83'],
gradientSet: ['#5f8b95', '#ba4d51']
},
'harmony light': {
simpleSet: ['#fcb65e', '#679ec5', '#ad79ce', '#7abd5c', '#e18e92', '#b6d623', '#b7abea', '#85dbd5'],
indicatingSet: ['#b6d623', '#fcb65e', '#e18e92'],
gradientSet: ['#7abd5c', '#fcb65e']
},
'soft pastel': {
simpleSet: ['#60a69f', '#78b6d9', '#6682bb', '#a37182', '#eeba69', '#90ba58', '#456c68', '#7565a4'],
indicatingSet: ['#90ba58', '#eeba69', '#a37182'],
gradientSet: ['#78b6d9', '#eeba69']
},
pastel: {
simpleSet: ['#bb7862', '#70b3a1', '#bb626a', '#057d85', '#ab394b', '#dac599', '#153459', '#b1d2c6'],
indicatingSet: ['#70b3a1', '#dac599', '#bb626a'],
gradientSet: ['#bb7862', '#70b3a1']
},
bright: {
simpleSet: ['#70c92f', '#f8ca00', '#bd1550', '#e97f02', '#9d419c', '#7e4452', '#9ab57e', '#36a3a6'],
indicatingSet: ['#70c92f', '#f8ca00', '#bd1550'],
gradientSet: ['#e97f02', '#f8ca00']
},
soft: {
simpleSet: ['#cbc87b', '#9ab57e', '#e55253', '#7e4452', '#e8c267', '#565077', '#6babac', '#ad6082'],
indicatingSet: ['#9ab57e', '#e8c267', '#e55253'],
gradientSet: ['#9ab57e', '#e8c267']
},
ocean: {
simpleSet: ['#75c099', '#acc371', '#378a8a', '#5fa26a', '#064970', '#38c5d2', '#00a7c6', '#6f84bb'],
indicatingSet: ['#c8e394', '#7bc59d', '#397c8b'],
gradientSet: ['#acc371', '#38c5d2']
},
vintage: {
simpleSet: ['#dea484', '#efc59c', '#cb715e', '#eb9692', '#a85c4c', '#f2c0b5', '#c96374', '#dd956c'],
indicatingSet: ['#ffe5c6', '#f4bb9d', '#e57660'],
gradientSet: ['#efc59c', '#cb715e']
},
violet: {
simpleSet: ['#d1a1d1', '#eeacc5', '#7b5685', '#7e7cad', '#a13d73', '#5b41ab', '#e287e2', '#689cc1'],
indicatingSet: ['#d8e2f6', '#d0b2da', '#d56a8a'],
gradientSet: ['#eeacc5', '#7b5685']
}
};
var currentPaletteName = 'default';
function currentPalette(name) {
if (name === undefined)
return currentPaletteName;
else {
name = String(name).toLowerCase();
currentPaletteName = name in palettes ? name : 'default'
}
}
function getPalette(palette, parameters) {
var result;
if (_isArray(palette))
result = palette;
else {
parameters = parameters || {};
var type = parameters.type || 'simpleSet';
if (_isString(palette)) {
var name = palette.toLowerCase(),
baseContainer = palettes[name],
themedContainer = parameters.theme && palettes[name + '_' + _String(parameters.theme).toLowerCase()];
result = themedContainer && themedContainer[type] || baseContainer && baseContainer[type]
}
if (!result)
result = palettes[currentPaletteName][type]
}
return result ? result.slice(0) : null
}
function registerPalette(name, palette, theme) {
var item = {};
if (_isArray(palette))
item.simpleSet = palette.slice(0);
else if (palette) {
item.simpleSet = _isArray(palette.simpleSet) ? palette.simpleSet.slice(0) : undefined;
item.indicatingSet = _isArray(palette.indicatingSet) ? palette.indicatingSet.slice(0) : undefined;
item.gradientSet = _isArray(palette.gradientSet) ? palette.gradientSet.slice(0) : undefined
}
if (item.simpleSet || item.indicatingSet || item.gradientSet) {
var paletteName = _String(name).toLowerCase();
if (theme)
paletteName = paletteName + '_' + _String(theme).toLowerCase();
_extend(palettes[paletteName] = palettes[paletteName] || {}, item)
}
}
function RingBuf(buf) {
var ind = 0;
this.next = function() {
var res = buf[ind++];
if (ind == buf.length)
this.reset();
return res
};
this.reset = function() {
ind = 0
}
}
function Palette(palette, parameters) {
parameters = parameters || {};
this._originalPalette = getPalette(palette, parameters);
var stepHighlight = parameters ? parameters.stepHighlight || 0 : 0;
this._paletteSteps = new RingBuf([0, stepHighlight, -stepHighlight]);
this._resetPalette()
}
_extend(Palette.prototype, {
dispose: function() {
this._originalPalette = this._palette = this._paletteSteps = null;
return this
},
getNextColor: function() {
var that = this;
if (that._currentColor >= that._palette.length)
that._resetPalette();
return that._palette[that._currentColor++]
},
_resetPalette: function() {
var that = this;
that._currentColor = 0;
var step = that._paletteSteps.next(),
originalPalette = that._originalPalette;
if (step) {
var palette = that._palette = [],
i = 0,
ii = originalPalette.length;
for (; i < ii; ++i)
palette[i] = getNewColor(originalPalette[i], step)
}
else
that._palette = originalPalette.slice(0)
},
reset: function() {
this._paletteSteps.reset();
this._resetPalette();
return this
}
});
function getNewColor(currentColor, step) {
var newColor = new _Color(currentColor).alter(step),
lightness = getLightness(newColor);
if (lightness > 200 || lightness < 55)
newColor = new _Color(currentColor).alter(-step / 2);
return newColor.toHex()
}
function getLightness(color) {
return color.r * 0.3 + color.g * 0.59 + color.b * 0.11
}
function GradientPalette(source, size) {
var palette = getPalette(source, {type: 'gradientSet'});
palette = size > 0 ? createGradientColors(palette[0], palette[1], size) : [];
this.getColor = function(index) {
return palette[index] || null
};
this._DEBUG_source = source;
this._DEBUG_size = size
}
function createGradientColors(start, end, count) {
var startColor = new _Color(start),
endColor = new _Color(end);
if (count === 1)
return [startColor.blend(endColor, 0.5).toHex()];
else {
var list = [],
step = 1 / (count - 1),
i,
ii = count;
list.push(0);
for (i = 1; i < ii - 1; ++i)
list.push(step * i);
list.push(1);
for (i = 0; i < ii; ++i)
list[i] = startColor.blend(endColor, list[i]).toHex();
return list
}
}
_extend(DX.viz.core, {
registerPalette: registerPalette,
getPalette: getPalette,
Palette: Palette,
GradientPalette: GradientPalette,
currentPalette: currentPalette
});
DX.viz.core._DEBUG_palettes = palettes
})(DevExpress, jQuery);
/*! Module viz-core, file baseThemeManager.js */
(function(DX, $, undefined) {
var _isString = DX.utils.isString,
_findTheme = DX.viz.core.findTheme,
_extend = $.extend,
_each = $.each;
DX.viz.core.BaseThemeManager = DX.Class.inherit({
dispose: function() {
this._theme = this._font = null;
return this
},
setTheme: function(theme) {
theme = theme || {};
var that = this,
themeObj = _findTheme(_isString(theme) ? theme : theme.name);
that._themeName = themeObj.name;
that._font = _extend({}, themeObj.font, theme.font);
that._themeSection && _each(that._themeSection.split('.'), function(_, path) {
themeObj = _extend(true, {}, themeObj[path], that._IE8 ? themeObj[path + 'IE8'] : {})
});
that._theme = _extend(true, {}, themeObj, _isString(theme) ? {} : theme);
that._initializeTheme();
return that
},
theme: function() {
return this._theme
},
themeName: function() {
return this._themeName
},
_initializeTheme: function(){},
_initializeFont: function(font) {
_extend(font, this._font, _extend({}, font))
}
})
})(DevExpress, jQuery);
/*! Module viz-core, file textCloud.js */
(function(DX, undefined) {
var min = Math.min;
DX.viz.core.TextCloud = DX.Class.inherit(function() {
var DEFAULT_OPTIONS = {
horMargin: 8,
verMargin: 4,
tailLength: 10
};
var COEFFICIENTS_MAP = {};
COEFFICIENTS_MAP['right-bottom'] = COEFFICIENTS_MAP['rb'] = [0, -1, -1, 0, 0, 1, 1, 0];
COEFFICIENTS_MAP['bottom-right'] = COEFFICIENTS_MAP['br'] = [-1, 0, 0, -1, 1, 0, 0, 1];
COEFFICIENTS_MAP['left-bottom'] = COEFFICIENTS_MAP['lb'] = [0, -1, 1, 0, 0, 1, -1, 0];
COEFFICIENTS_MAP['bottom-left'] = COEFFICIENTS_MAP['bl'] = [1, 0, 0, -1, -1, 0, 0, 1];
COEFFICIENTS_MAP['left-top'] = COEFFICIENTS_MAP['lt'] = [0, 1, 1, 0, 0, -1, -1, 0];
COEFFICIENTS_MAP['top-left'] = COEFFICIENTS_MAP['tl'] = [1, 0, 0, 1, -1, 0, 0, -1];
COEFFICIENTS_MAP['right-top'] = COEFFICIENTS_MAP['rt'] = [0, 1, -1, 0, 0, -1, 1, 0];
COEFFICIENTS_MAP['top-right'] = COEFFICIENTS_MAP['tr'] = [-1, 0, 0, 1, 1, 0, 0, -1];
return {
setup: function(options) {
var that = this,
ops = $.extend({}, DEFAULT_OPTIONS, options),
x = ops.x,
y = ops.y,
type = COEFFICIENTS_MAP[ops.type],
cloudWidth = ops.textWidth + 2 * ops.horMargin,
cloudHeight = ops.textHeight + 2 * ops.verMargin,
tailWidth = ops.tailLength,
tailHeight = tailWidth,
cx = x,
cy = y;
if (type[0] & 1)
tailHeight = min(tailHeight, cloudHeight / 3);
else
tailWidth = min(tailWidth, cloudWidth / 3);
that._points = [x, y, x += type[0] * (cloudWidth + tailWidth), y += type[1] * (cloudHeight + tailHeight), x += type[2] * cloudWidth, y += type[3] * cloudHeight, x += type[4] * cloudWidth, y += type[5] * cloudHeight, x += type[6] * (cloudWidth - tailWidth), y += type[7] * (cloudHeight - tailHeight)];
that._cx = cx + type[0] * tailWidth + (type[0] + type[2]) * cloudWidth / 2;
that._cy = cy + type[1] * tailHeight + (type[1] + type[3]) * cloudHeight / 2;
that._cloudWidth = cloudWidth;
that._cloudHeight = cloudHeight;
that._tailLength = ops.tailLength;
return that
},
points: function() {
return this._points.slice(0)
},
cx: function() {
return this._cx
},
cy: function() {
return this._cy
},
width: function() {
return this._cloudWidth
},
height: function() {
return this._cloudHeight
},
tailLength: function() {
return this._tailLength
}
}
}())
})(DevExpress);
/*! Module viz-core, file parseUtils.js */
(function($, DX) {
var viz = DX.viz,
core = viz.core,
Class = DX.Class,
isDefined = DX.utils.isDefined;
var parseUtils = Class.inherit({
ctor: function(options) {
options = options || {};
this._incidentOccured = $.isFunction(options.incidentOccured) ? options.incidentOccured : $.noop
},
correctValueType: function(type) {
return type === 'numeric' || type === 'datetime' || type === 'string' ? type : ''
},
_parsers: {
string: function(val) {
return isDefined(val) ? '' + val : val
},
numeric: function(val) {
if (!isDefined(val))
return val;
var parsedVal = Number(val);
if (isNaN(parsedVal))
parsedVal = undefined;
return parsedVal
},
datetime: function(val) {
if (!isDefined(val))
return val;
var parsedVal,
numVal = Number(val);
if (!isNaN(numVal))
parsedVal = new Date(numVal);
else
parsedVal = new Date(val);
if (isNaN(Number(parsedVal)))
parsedVal = undefined;
return parsedVal
}
},
getParser: function(valueType, entity) {
var that = this,
parser,
message = 'valueType is unknown.';
if (entity)
message = 'The type specified as the "valueType" field of the ' + entity + ' configuration object is unknown.';
valueType = that.correctValueType(valueType);
parser = that._parsers[valueType];
if (!parser)
this._incidentOccured.call(null, message);
return parser || $.noop
}
});
core.ParseUtils = parseUtils
})(jQuery, DevExpress);
/*! Module viz-core, file utils.js */
(function($, DX) {
var core = DX.viz.core,
math = Math;
core.utils = {decreaseGaps: function(object, keys, decrease) {
var arrayGaps,
eachDecrease,
middleValue;
do {
arrayGaps = $.map(keys, function(key) {
return object[key] ? object[key] : null
});
middleValue = math.ceil(decrease / arrayGaps.length);
arrayGaps.push(middleValue);
eachDecrease = math.min.apply(null, arrayGaps);
$.each(keys, function(_, key) {
if (object[key]) {
object[key] -= eachDecrease;
decrease -= eachDecrease
}
})
} while (decrease > 0 && arrayGaps.length > 1);
return decrease
}}
})(jQuery, DevExpress);
/*! Module viz-core, file loadIndicator.js */
(function($, DX) {
var viz = DX.viz,
core = viz.core,
ANIMATION_SETTINGS = {
easing: 'linear',
duration: 150
},
INVISIBLE_POINT = {
x: -10000,
y: -10000
};
var applySettings = function(element, settings, animate, complete) {
var prevAnimation = element.animation;
if (prevAnimation) {
prevAnimation.options.complete = null;
prevAnimation.stop()
}
if (animate)
element.animate(settings, {complete: complete});
else {
element.applySettings(settings);
complete && complete()
}
};
core.LoadIndicator = DX.Class.inherit({
ctor: function(options, widgetContainer) {
var that = this;
that._$widgetContainer = $(widgetContainer);
that._$container = $('
', {css: {
position: 'relative',
height: 0,
padding: 0,
margin: 0,
border: 0
}}).appendTo(that._$widgetContainer);
that._updateContainer();
that.applyOptions(options);
that._endLoadingCompleteHandler = function() {
that._endLoad = false;
that._externalComplete && that._externalComplete();
that._externalComplete = null;
that._onCompleteAction && that[that._onCompleteAction]();
that._onCompleteAction = null
};
that._$container.hide()
},
_updateRenderer: function(width, height, top) {
if (this._renderer)
this._renderer.recreateCanvas(width, height);
else if (this._$container.get(0)) {
this._renderer = new viz.renderers.Renderer({
width: width,
height: height,
animation: ANIMATION_SETTINGS
});
this._renderer.draw(this._$container[0])
}
this._renderer && this._renderer.getRoot().applySettings({style: {
position: 'absolute',
top: top,
left: 0
}});
return this._renderer
},
applyOptions: function(options, width, height) {
var pane = this._pane;
if (pane && options) {
pane.rect.applySettings({fill: options.backgroundColor});
pane.text.applySettings({
font: options.font,
text: options.text
})
}
if (this.isShown && (width || height))
this._updateContainer(width, height)
},
_draw: function() {
var pane,
renderer = this._renderer;
if (renderer) {
pane = this._pane = {};
pane.rect = renderer.createRect(0, 0, 0, 0, 0, {opacity: 0}).append();
pane.text = renderer.createText('', 0, 0, {
align: 'center',
translateX: INVISIBLE_POINT.x,
translateY: INVISIBLE_POINT.y
}).append()
}
},
_updateContainer: function(width, height) {
var that = this,
$widgetContainer = that._$widgetContainer,
canvasTop;
width = width || $widgetContainer.width();
height = height || $widgetContainer.height();
if ($widgetContainer.get(0))
canvasTop = $widgetContainer.offset().top - that._$container.offset().top;
else
canvasTop = -height;
that._updateRenderer(width, height, canvasTop);
if (!that._pane)
that._draw();
else {
that._pane.rect.applySettings({
width: width,
height: height
});
that._pane.text.move(width / 2, height / 2)
}
},
dispose: function() {
this._$widgetContainer = null;
this._$container.remove().detach();
this._$container = null;
this._renderer.dispose();
this._renderer = null;
this._pane = null
},
toForeground: function() {
this._$container.appendTo(this._$widgetContainer)
},
show: function(width, height) {
if (this._endLoad) {
this._onCompleteAction = 'show';
return
}
this._$container.show();
this._updateContainer(width, height);
applySettings(this._pane.rect, {opacity: 0.85}, true);
this.isShown = true
},
endLoading: function(complete, disableAnimation) {
this._externalComplete = complete;
if (this._endLoad)
return;
if (this.isShown) {
this._endLoad = true;
applySettings(this._pane.rect, {opacity: 1}, !disableAnimation, this._endLoadingCompleteHandler)
}
else
complete && complete()
},
hide: function() {
var that = this;
if (this._endLoad) {
this._onCompleteAction = 'hide';
return
}
if (this.isShown) {
this._pane.text.move(INVISIBLE_POINT.x, INVISIBLE_POINT.y);
applySettings(that._pane.rect, {opacity: 0}, true, function() {
that._$container.hide()
});
this.isShown = false
}
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file tooltip.js */
(function($, DX, undefined) {
var ARROW_WIDTH = 20,
MAX_SHADOW_SIZE = 10,
formatHelper = DX.formatHelper,
X_INTERVAL = 15,
_max = Math.max,
_round = Math.round,
_isFunction = DX.utils.isFunction,
_isDefined = DX.utils.isDefined,
_extend = $.extend,
FORMAT_PRECISION = {
argument: ['argumentFormat', 'argumentPrecision'],
percent: ['percent', 'percentPrecision'],
value: ['format', 'precision']
},
VISIBLE = {visibility: 'visible'},
HIDDEN = {visibility: 'hidden'},
LEFT = 'left',
RIGHT = 'right';
DX.viz.core.Tooltip = DX.Class.inherit({
ctor: function(options, group, renderer) {
this._state = {};
this._options = {};
this._renderer = renderer;
this._group = group;
this._cloud = renderer.createArea();
this._textGroup = renderer.createGroup();
if (!$.isEmptyObject(options))
this.update(options);
this._createTextContent()
},
dispose: function() {
this._shadow.dispose();
this._shadow = null;
this._cloud = null;
this._text = null;
this._group = null;
this._options = null;
this._renderer = null;
this._tooltipTextArray = null;
this._textGroup = null;
return this
},
update: function(options) {
options = options || {};
var that = this,
group = that._group,
shadowOptions = options.shadow || {},
shadow = that._shadow = that._shadow || that._renderer.createFilter('shadow').applySettings({
width: '200%',
height: '200%',
color: shadowOptions.color,
opacity: shadowOptions.opacity,
dx: shadowOptions.offsetX,
dy: shadowOptions.offsetY,
blur: shadowOptions.blur,
x: '-50%',
y: '-50%'
}),
borderSettings = options.border,
shapeSettings = _extend({
opacity: options.opacity,
filter: shadow.append().ref
}, borderSettings && borderSettings.visible ? {
strokeWidth: borderSettings.width,
stroke: borderSettings.color,
strokeOpacity: borderSettings.opacity,
dashStyle: borderSettings.dashStyle
} : {
strokeWidth: null,
stroke: null
}),
textSettings = _extend({}, {
align: 'center',
font: options.font
}, options.text);
that._options = options;
that.setSize(options.canvasWidth, options.canvasHeight);
that._customizeTooltip = _isFunction(options.customizeTooltip) ? options.customizeTooltip : null;
if (!that._customizeTooltip && _isFunction(options.customizeText))
that._customizeTooltip = function() {
return {text: options.customizeText.apply(this, arguments)}
};
that._cloud.applySettings(shapeSettings).append(group);
that._text && options.font && that._text.applySettings({font: {size: options.font.size}});
that._textGroup.applySettings(textSettings).append(group);
that.hide();
return that
},
formatValue: function(value, specialFormat) {
var formatObj = FORMAT_PRECISION[specialFormat || 'value'],
format = formatObj[0] in this._options ? this._options[formatObj[0]] : specialFormat;
return formatHelper.format(value, format, this._options[formatObj[1]] || 0)
},
prepare: function(formatObject, params, defaultTextValueField) {
this._state = this._state || {};
defaultTextValueField = defaultTextValueField || 'valueText';
var defaultText = formatObject[defaultTextValueField] || '';
_extend(this._state, params);
if (this._customizeTooltip) {
var customize = this._customizeTooltip.call(formatObject, formatObject);
customize = $.isPlainObject(customize) ? customize : {};
if ('text' in customize)
this._state.text = _isDefined(customize.text) ? String(customize.text) : '';
else {
if ($.isArray(defaultText)) {
this._options._justify = true;
this._createTextContent();
defaultText = defaultText.join('
')
}
this._state.text = defaultText
}
this._state.color = customize.color || this._options.color
}
else {
this._state.text = defaultText;
this._state.color = this._options.color
}
if (this._options._justify)
this._state.text = this._state.text.split('
');
if (this._state.visibility == VISIBLE && !!this._state.text)
this.show();
return !!this._state.text
},
enabled: function() {
return !!this._options.enabled
},
formatColorTooltip: function(that) {
return that._customizeTooltip && that._customizeTooltip.call(this, this)
},
_getData: function() {
var that = this,
x = that._state.x,
y = that._state.y,
xt = x,
yt = y,
align = 'center',
points = [],
bbox = that._state.textBBox,
options = that._options,
paddingLeftRight = options.paddingLeftRight,
paddingTopBottom = options.paddingTopBottom,
arrowLength = options.arrowLength > 0 ? options.arrowLength : 0,
horPosition = options.cloudHorizontalPosition,
verPosition = options.cloudVerticalPosition,
isHorPositionDefined = horPosition !== undefined && horPosition !== null,
isVerPositionDefined = verPosition !== undefined && verPosition !== null,
cloudWidth = bbox.width + paddingLeftRight * 2,
cloudHeight = bbox.height + paddingTopBottom * 2,
updatedText;
updatedText = that._checkWidthText(cloudWidth, cloudHeight);
if (updatedText) {
that._state.textBBox = bbox = updatedText.bbox;
cloudWidth = updatedText.cloudWidth;
cloudHeight = updatedText.cloudHeight;
paddingLeftRight = updatedText.paddingLeftRight;
paddingTopBottom = updatedText.paddingTopBottom
}
if (isHorPositionDefined ? horPosition === RIGHT : cloudWidth / 2 > x) {
points = that._setArrowLeft(cloudWidth, cloudHeight, arrowLength, x, y);
align = LEFT;
xt += paddingLeftRight
}
else if (isHorPositionDefined ? horPosition === LEFT : x + cloudWidth / 2 > that._canvasWidth) {
points = that._setArrowRight(cloudWidth, cloudHeight, arrowLength, x, y);
align = RIGHT;
xt -= paddingLeftRight
}
else
points = that._setArrowCenter(cloudWidth, cloudHeight, arrowLength, x, y);
if (isVerPositionDefined ? verPosition === 'top' : cloudHeight + arrowLength < y) {
yt -= arrowLength + cloudHeight / 2 - bbox.height / 2 + that._state.offset;
that.tooltipInverted = false
}
else {
yt += arrowLength + cloudHeight / 2 + bbox.height / 2 + that._state.offset;
that.tooltipInverted = true
}
yt = that._correctYTextContent(yt);
return {
points: points,
text: {
x: xt,
y: yt,
align: align
}
}
},
_updateTextContent: function() {
if (this._options._justify) {
this._textGroup.clear();
this._calculateTextContent();
this._locateTextContent(0, 0, 'center')
}
else
this._text.updateText(this._state.text);
this._state.textBBox = this._textGroup.getBBox()
},
_correctYTextContent: function(y) {
var bbox;
if (this._options._justify) {
this._locateTextContent(0, y, 'center');
bbox = this._textGroup.getBBox()
}
else {
this._text.applySettings({y: y});
bbox = this._text.getBBox()
}
return y - (bbox.y + bbox.height - y)
},
_adjustTextContent: function(data) {
if (this._options._justify)
this._locateTextContent(data.text.x, data.text.y, data.text.align);
else
this._text.applySettings({
x: data.text.x,
y: data.text.y,
align: data.text.align
})
},
_updateTooltip: function() {
var that = this,
box,
data,
scale;
data = that._getData();
that._cloud.applySettings({
points: data.points,
fill: that._state.color,
'class': that._state.className
});
that._adjustTextContent(data);
box = that._group.getBBox();
if (box.y + box.height > that._canvasHeight) {
scale = (that._canvasHeight - box.y) / box.height;
that._group.applySettings({
scale: scale,
translateX: that._state.x * (1 - scale),
translateY: that._state.y * (1 - scale)
})
}
else
that._group.applySettings({
scale: 1,
translateX: 0,
translateY: 0
})
},
_createTextContent: function() {
var that = this,
options = that._options,
fontSize;
that._textGroup.clear();
that._text = null;
if (!options._justify) {
fontSize = options.font && options.font.size;
that._text = that._renderer.createText(undefined, 0, 0, {font: {size: fontSize}}).append(that._textGroup)
}
},
_getTextContentParams: function() {
var that = this,
i,
text,
textBBox,
textArray = that._state.text,
textArrayLength = textArray.length,
textParams = {
width: [],
height: []
};
that._tooltipTextArray = [];
for (i = 0; i < textArrayLength; i++) {
text = that._renderer.createText(textArray[i], 0, 0, {}).append(this._textGroup);
that._tooltipTextArray.push(text);
textBBox = text.getBBox();
textParams.width.push(textBBox.width)
}
that._lineHeight = -2 * textBBox.y - textBBox.height;
return textParams
},
_locateTextContent: function(x, y, alignment) {
var that = this,
tooltipTextArray = that._tooltipTextArray,
textWidth = that._textContentWidth,
lineSpacing = that._options.lineSpacing,
yDelta = (lineSpacing > 0 ? lineSpacing : 0) + that._lineHeight,
leftXCoord,
rightXCoord,
i,
rtl = that._options._rtl;
if (alignment === LEFT)
leftXCoord = x;
else if (alignment === RIGHT)
leftXCoord = x - textWidth;
else
leftXCoord = _round(x - textWidth / 2);
rightXCoord = leftXCoord + textWidth;
for (i = tooltipTextArray.length - 1; i >= 0; i -= 2) {
tooltipTextArray[i].applySettings({
x: !rtl ? rightXCoord : leftXCoord,
y: y,
align: !rtl ? RIGHT : LEFT
});
if (tooltipTextArray[i - 1])
tooltipTextArray[i - 1].applySettings({
x: !rtl ? leftXCoord : rightXCoord,
y: y,
align: !rtl ? LEFT : RIGHT
});
y -= yDelta
}
},
_calculateTextContent: function() {
var that = this,
textArray = that._state.text,
textArrayLength = textArray.length,
textParams,
width,
stringWidthArray = [],
i;
textParams = that._getTextContentParams();
for (i = 0; i < textArrayLength; i += 2) {
if (textParams.width[i + 1])
width = textParams.width[i] + X_INTERVAL + textParams.width[i + 1];
else
width = textParams.width[i];
stringWidthArray.push(width)
}
that._textContentWidth = _max.apply(null, stringWidthArray)
},
setSize: function(width, height) {
this._canvasWidth = _isDefined(width) ? width : this._canvasWidth;
this._canvasHeight = _isDefined(height) ? height : this._canvasHeight;
return this
},
getBBox: function() {
var that = this,
options = that._options,
paddingLeftRight = options.paddingLeftRight || 0,
paddingTopBottom = options.paddingTopBottom || 0,
borderWidth = options.border.visible && options.border.width || 0,
tooltipBBox = that._textGroup.getBBox();
return tooltipBBox.isEmpty ? tooltipBBox : {
x: tooltipBBox.x - paddingLeftRight - borderWidth / 2 - MAX_SHADOW_SIZE,
y: tooltipBBox.y - paddingTopBottom - borderWidth / 2 - MAX_SHADOW_SIZE,
height: tooltipBBox.height + 2 * paddingTopBottom + borderWidth + MAX_SHADOW_SIZE * 2,
width: tooltipBBox.width + 2 * paddingLeftRight + borderWidth + MAX_SHADOW_SIZE * 2,
isEmpty: false
}
},
show: function() {
this._state.visibility = VISIBLE;
this._updateTextContent();
this.move(this._state.x, this._state.y, this._state.offset);
this._cloud.applySettings(VISIBLE);
this._textGroup.applySettings(VISIBLE);
return this
},
hide: function() {
this._state.visibility = HIDDEN;
this._cloud.applySettings(HIDDEN);
this._textGroup.applySettings(HIDDEN);
return this
},
move: function(x, y, offset) {
this._state.x = _isDefined(x) ? x : this._state.x || 0;
this._state.y = _isDefined(y) ? y : this._state.y || 0;
this._state.offset = _isDefined(offset) ? offset : this._state.offset || 0;
this._updateTooltip();
return this
},
_setArrowCenter: function(cloudWidth, cloudHeight, arrowLength, x, y) {
var that = this,
position = that._options.cloudVerticalPosition,
isPosDefined = position !== undefined && position !== null,
verticalInvert = !(isPosDefined ? position === 'top' : cloudHeight + arrowLength < y),
x0 = x,
y0 = verticalInvert ? y + that._state.offset : y - that._state.offset,
x1 = x0 + ARROW_WIDTH / 2,
y1 = verticalInvert ? y0 + arrowLength : y0 - arrowLength,
x2 = x1 + cloudWidth / 2 - ARROW_WIDTH / 2,
y2 = y1,
x3 = x2,
y3 = verticalInvert ? y2 + cloudHeight : y2 - cloudHeight,
x4 = x3 - cloudWidth,
y4 = y3,
x5 = x4,
y5 = verticalInvert ? y4 - cloudHeight : y4 + cloudHeight,
x6 = x5 + cloudWidth / 2 - ARROW_WIDTH / 2,
y6 = y5;
return [x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6]
},
_setArrowLeft: function(cloudWidth, cloudHeight, arrowLength, x, y) {
var that = this,
position = that._options.cloudVerticalPosition,
isPosDefined = position !== undefined && position !== null,
verticalInvert = !(isPosDefined ? position === 'top' : cloudHeight + arrowLength < y),
x0 = x,
y0 = verticalInvert ? y + that._state.offset : y - that._state.offset,
x1 = x0 + ARROW_WIDTH,
y1 = verticalInvert ? y0 + arrowLength : y0 - arrowLength,
x2 = x1 + cloudWidth - ARROW_WIDTH,
y2 = y1,
x3 = x2,
y3 = verticalInvert ? y2 + cloudHeight : y2 - cloudHeight,
x4 = x3 - cloudWidth,
y4 = y3,
x5 = x4,
y5 = verticalInvert ? y4 - cloudHeight - arrowLength : y4 + cloudHeight + arrowLength;
return [x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5]
},
_setArrowRight: function(cloudWidth, cloudHeight, arrowLength, x, y) {
var that = this,
position = that._options.cloudVerticalPosition,
isPosDefined = position !== undefined && position !== null,
verticalInvert = !(isPosDefined ? position === 'top' : cloudHeight + arrowLength < y),
x0 = x,
y0 = verticalInvert ? y + that._state.offset : y - that._state.offset,
x1 = x0,
y1 = verticalInvert ? y0 + arrowLength + cloudHeight : y0 - arrowLength - cloudHeight,
x2 = x1 - cloudWidth,
y2 = y1,
x3 = x2,
y3 = verticalInvert ? y2 - cloudHeight : y2 + cloudHeight,
x4 = x3 + cloudWidth - ARROW_WIDTH,
y4 = y3,
x5 = x4 + ARROW_WIDTH,
y5 = verticalInvert ? y4 - arrowLength : y4 + arrowLength;
return [x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5]
},
_checkWidthText: function(cloudWidth, cloudHeight) {
if (this._options._justify)
return;
var x = this._state.x,
text = this._state.text,
index,
paddingLeftRight = this._options.paddingLeftRight,
paddingTopBottom = this._options.paddingTopBottom,
textLength,
maxTooltipWidth,
remainLength,
newIndex,
bbox = this._state.textBBox;
if (cloudWidth < x || x + cloudWidth < this._canvasWidth || cloudWidth / 2 < x && x + cloudWidth / 2 < this._canvasWidth)
return false;
if (text.indexOf("
") === -1 && text.indexOf(" ") !== -1) {
maxTooltipWidth = _max(x, this._canvasWidth - x, 2 * Math.min(x, this._canvasWidth - x));
textLength = text.length * maxTooltipWidth / bbox.width;
index = text.substr(0, ~~textLength).lastIndexOf(" ");
if (index === -1)
index = text.substr(0).indexOf(" ");
remainLength = text.substr(index + 1).length;
this._state.text = text.substr(0, index) + "
";
while (textLength <= remainLength) {
newIndex = text.substr(index + 1, ~~textLength).lastIndexOf(" ");
if (newIndex === -1)
newIndex = text.substr(index + 1).indexOf(" ");
if (newIndex !== -1) {
this._state.text += text.substr(index + 1, newIndex) + "
";
remainLength = text.substr(index + 1 + newIndex).length;
index += newIndex + 1
}
else
break
}
this._state.text += text.substr(index + 1);
this._text.updateText(this._state.text);
bbox = this._text.getBBox();
cloudWidth = bbox.width + paddingLeftRight * 2;
cloudHeight = bbox.height + paddingTopBottom * 2
}
if (cloudWidth > x && x + cloudWidth > this._canvasWidth && (cloudWidth / 2 > x || x + cloudWidth / 2 > this._canvasWidth)) {
paddingLeftRight = 5;
paddingTopBottom = 5;
cloudWidth = bbox.width + 2 * paddingLeftRight;
cloudHeight = bbox.height + 2 * paddingTopBottom
}
return {
bbox: bbox,
cloudWidth: cloudWidth,
cloudHeight: cloudHeight,
paddingTopBottom: paddingTopBottom,
paddingLeftRight: paddingLeftRight
}
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file legend.js */
(function(DX, $, undefined) {
var DEFAULT_MARGIN = 10,
_math = Math,
_round = _math.round,
_ceil = _math.ceil,
_floor = _math.floor,
CENTER = 'center',
RIGHT = 'right',
LEFT = 'left',
TOP = 'top',
BOTTOM = 'bottom',
HORIZONTAL = 'horizontal',
VERTICAL = 'vertical',
INSIDE = 'inside',
OUTSIDE = 'outside',
NONE = 'none',
decreaseGaps = DevExpress.viz.core.utils.decreaseGaps,
DEFAULT_MARKER_HATCHING_WIDTH = 2,
DEFAULT_MARKER_HATCHING_STEP = 5;
function getPatternId(renderer, states, action, color) {
if (!states)
return;
var direction = states[action].hatching.direction,
hatching,
colorFromAction = states[action].fill;
color = colorFromAction === NONE ? color : colorFromAction;
direction = !direction || direction === NONE ? RIGHT : direction;
hatching = $.extend({}, states[action].hatching, {
direction: direction,
step: DEFAULT_MARKER_HATCHING_STEP,
width: DEFAULT_MARKER_HATCHING_WIDTH
});
return renderer.createPattern(color, hatching).append().id
}
function getMaxBBox(groups) {
var maxWidth = 0,
maxHeight = 0,
bbox;
$.each(groups, function(_, group) {
bbox = group.getBBox();
if (bbox.width > maxWidth)
maxWidth = bbox.width;
if (bbox.height > maxHeight)
maxHeight = bbox.height
});
return {
width: maxWidth,
height: maxHeight
}
}
DX.viz.core.Legend = DX.Class.inherit({
ctor: function(data, options, renderer, group) {
var that = this;
that._renderer = renderer;
that._legendGroup = group;
that._markersPatternsIds = [];
that._data = data;
that._init(options)
},
_init: function(options) {
if (!options)
return;
var debug = DX.utils.debug;
debug.assertParam(options.visible, 'Visibility was not passed');
debug.assertParam(options.markerSize, 'markerSize was not passed');
debug.assertParam(options.font.color, 'fontColor was not passed');
debug.assertParam(options.font.family, 'fontFamily was not passed');
debug.assertParam(options.font.size, 'fontSize was not passed');
debug.assertParam(options.paddingLeftRight, 'paddingLeftRight was not passed');
debug.assertParam(options.paddingTopBottom, 'paddingTopBottom was not passed');
debug.assertParam(options.columnItemSpacing, 'columnItemSpacing was not passed');
debug.assertParam(options.rowItemSpacing, 'rowItemSpacing was not passed');
debug.assertParam(options.equalColumnWidth, 'equalColumnWidth was not passed');
var that = this,
i;
that._parseMargins(options);
that._parseAlignments(options);
options.orientation = (options.orientation || '').toLowerCase();
if (options.orientation !== VERTICAL && options.orientation !== HORIZONTAL) {
if (options.horizontalAlignment === CENTER)
options.orientation = HORIZONTAL;
if (options.horizontalAlignment === RIGHT || options.horizontalAlignment === LEFT)
options.orientation = VERTICAL
}
if (!options.itemTextPosition)
options.itemTextPosition = options.orientation === HORIZONTAL ? BOTTOM : RIGHT;
else
options.itemTextPosition = options.itemTextPosition;
options.position = (options.position || '').toLowerCase();
if (options.position !== OUTSIDE && options.position !== INSIDE)
options.position = OUTSIDE;
options.hoverMode = (options.hoverMode || '').toLowerCase();
options.customizeText = $.isFunction(options.customizeText) ? options.customizeText : function() {
return this.seriesName
};
that._options = options;
!that._trackerGroup && (that._trackerGroup = that._renderer.createGroup({
'class': 'dxc-legend-trackers',
stroke: NONE,
fill: 'grey',
opacity: 0.0001
}));
that.__initialized = true
},
_parseMargins: function(options) {
if (options.margin >= 0) {
options.margin = Number(options.margin);
options.margin = {
top: options.margin,
bottom: options.margin,
left: options.margin,
right: options.margin
}
}
else
options.margin = {
top: options.margin.top >= 0 ? Number(options.margin.top) : DEFAULT_MARGIN,
bottom: options.margin.bottom >= 0 ? Number(options.margin.bottom) : DEFAULT_MARGIN,
left: options.margin.left >= 0 ? Number(options.margin.left) : DEFAULT_MARGIN,
right: options.margin.right >= 0 ? Number(options.margin.right) : DEFAULT_MARGIN
}
},
_parseAlignments: function(options) {
options.horizontalAlignment = (options.horizontalAlignment || '').toLowerCase();
if (options.horizontalAlignment !== CENTER && options.horizontalAlignment !== RIGHT && options.horizontalAlignment !== LEFT)
options.horizontalAlignment = RIGHT;
options.verticalAlignment = (options.verticalAlignment || '').toLowerCase();
if (options.verticalAlignment !== TOP && options.verticalAlignment !== BOTTOM) {
if (options.horizontalAlignment === CENTER)
options.verticalAlignment = BOTTOM;
if (options.horizontalAlignment === RIGHT || options.horizontalAlignment === LEFT)
options.verticalAlignment = TOP
}
},
update: function(data, options) {
this._data = data;
this.boundingRect = {
width: 0,
height: 0,
x: 0,
y: 0
};
this._init(options);
return this
},
setSize: function(size) {
this._size = size;
return this
},
draw: function() {
if (!this._options)
return this;
var that = this,
renderer = that._renderer,
options = that._options,
items = that._data,
itemsLength = items.length,
seriesGroups = [],
i,
label,
marker,
singleSeriesGroup,
trackers = [],
insideLegendGroup,
markersId = new Array(itemsLength),
passedId,
border = options.border,
borderVisible = border.visible && border.width && border.color && border.color !== NONE,
markers = new Array(itemsLength);
if (!(options.visible && items && itemsLength)) {
that._disposeTrackers();
return that
}
that._cleanLegendGroups();
insideLegendGroup = that._insideLegendGroup = renderer.createGroup().append(that._legendGroup);
that._createBackground(borderVisible);
for (i = 0; i < itemsLength; i++) {
singleSeriesGroup = renderer.createGroup({'class': 'dxc-item'}).append(insideLegendGroup);
marker = that._createMarker(items[i], singleSeriesGroup, i);
passedId = items[i].id;
label = that._createLabel(items[i], passedId, singleSeriesGroup);
markersId[i] = passedId;
that._locateLabelAndMarker(label, marker);
markers[i] = marker;
trackers.push({
rect: renderer.createRect(0, 0, 0, 0, 0, {
stroke: NONE,
fill: 'grey',
opacity: 0.0001,
inh: true
}),
id: passedId
});
seriesGroups.push(singleSeriesGroup)
}
that._seriesGroups = seriesGroups;
that._trackers = trackers;
that.drawTrackers();
that._markers = markers;
that._markersId = markersId;
that._locateElements(options);
return that
},
_locateElements: function(options) {
var that = this,
border = options.border,
borderVisible = border.visible && border.width && border.color && border.color !== NONE;
that._moveInInitialValues();
that._locateRowsColumns(that._seriesGroups, that._trackers, that._data.length, that._background, options);
if (that._background)
that._adjustBackgroundSettings(that._background, borderVisible, options);
that._setBoundingRect(options)
},
_moveInInitialValues: function() {
var that = this;
that._legendGroup && that._legendGroup.move(0, 0);
that._trackerGroup && that._trackerGroup.move(0, 0);
that._background && that._background.applySettings({
x: 0,
y: 0,
width: 0,
height: 0
})
},
_applyMarkerOptions: function(marker, options) {
if (marker)
marker.applySettings(options)
},
applySelected: function(id) {
var index = this._getIndexById(id);
if (index !== null)
this._applyMarkerOptions(this._markers[index], {fill: this._markersPatternsIds[index].selectedPatternId});
return this
},
applyHover: function(id) {
var index = this._getIndexById(id);
if (index !== null)
this._applyMarkerOptions(this._markers[index], {fill: this._markersPatternsIds[index].hoverPatternId});
return this
},
resetItem: function(id) {
var index = this._getIndexById(id);
if (index !== null)
this._applyMarkerOptions(this._markers[index], {fill: this._data[index].color || this._data[index].states.normal.fill})
},
_getIndexById: function(id) {
var i,
markersId = this._markersId,
markersIdLen = markersId.length;
for (i = 0; i < markersIdLen; i++)
if (markersId[i] === id)
return i;
return null
},
drawTrackers: function() {
if (!this._options.visible || !this._insideLegendGroup)
return;
var that = this,
trackerGroup = that._trackerGroup.append(that._legendGroup);
$.each(that._trackers || [], function(i, tracker) {
var trackerRect = tracker.rect;
trackerRect.data({
itemIndex: tracker.id,
mode: that._options.hoverMode
});
trackerRect.append(trackerGroup)
});
return that
},
_disposeTrackers: function() {
var that = this;
$.each(that._trackers || [], function(_, tracker) {
tracker.rect.removeData()
});
that._trackers = null
},
_createMarker: function(data, group, markerIndex) {
var that = this,
renderer = that._renderer,
markersPatternsIds = that._markersPatternsIds,
size = that._options.markerSize,
states = data.states,
marker;
marker = renderer.createRect(0, 0, size, size, 0, {fill: data.color}).append(group);
markersPatternsIds[markerIndex] = {
hoverPatternId: getPatternId(renderer, states, 'hover', data.color),
selectedPatternId: getPatternId(renderer, states, 'selection', data.color)
};
return marker
},
_createLabel: function(data, index, group) {
var that = this,
options = that._options,
position = options.itemTextPosition,
align = position === TOP || position === BOTTOM ? CENTER : LEFT,
text,
label,
labelFormatObject = {
seriesName: data.text,
seriesNumber: index,
seriesColor: data.color
};
text = that._formatLabel.call(labelFormatObject, options);
label = that._renderer.createText(text, 0, 0, {
font: options.font,
align: align
}).append(group);
return label
},
_cleanLegendGroups: function() {
var that = this,
trackerGroup = that._trackerGroup,
legendGroup = that._legendGroup;
if (legendGroup) {
legendGroup.clear();
that._insideLegendGroup && that._insideLegendGroup.dispose();
that._insideLegendGroup = null
}
if (trackerGroup)
trackerGroup.clear()
},
_createBackground: function(borderVisible) {
var that = this,
options = that._options,
isInside = options.position === INSIDE,
color = options.backgroundColor,
fill = color || (isInside ? options.containerBackgroundColor : NONE);
if (isInside || color || borderVisible)
that._background = that._renderer.createRect(0, 0, 0, 0, 0, {
fill: fill,
'class': 'dxc-border'
}).append(that._insideLegendGroup)
},
_formatLabel: function(options) {
return options.customizeText.call(this, this)
},
_locateLabelAndMarker: function(label, marker) {
var that = this,
defaultXMargin = 7,
defaultTopMargin = 4,
defaultBottomMargin = 2,
labelX = 0,
labelY = 0,
markerX,
markerY,
labelBox = label.getBBox(),
markerWidth = that._options.markerSize,
markerHeight = markerWidth,
approximateLabelY = markerHeight / 2 - (labelBox.y + labelBox.height / 2),
approximateLabelX = markerWidth / 2 - (labelBox.x + labelBox.width / 2);
switch (that._options.itemTextPosition) {
case LEFT:
labelY = _round(approximateLabelY);
markerX = labelBox.width + defaultXMargin;
break;
case RIGHT:
labelX = markerWidth + defaultXMargin;
labelY = _round(approximateLabelY);
break;
case TOP:
labelX = _round(approximateLabelX);
markerY = defaultTopMargin;
break;
case BOTTOM:
labelX = _round(approximateLabelX);
labelY = markerHeight + defaultBottomMargin - labelBox.y;
break
}
label.applySettings({
x: labelX,
y: labelY
});
marker.applySettings({
x: markerX,
y: markerY
})
},
_locateRowsColumns: function(groups, trackers, count, background, options) {
var that = this,
itemTextPosition = options.itemTextPosition,
size = that._size,
legendBox,
rowsColumns = that._getRowsColumns(count),
rows = rowsColumns.rows,
columns = rowsColumns.columns,
margin = options.margin,
paddingLeftRight = background ? options.paddingLeftRight : 0,
paddingTopBottom = background ? options.paddingTopBottom : 0,
placeholderWidth = size.width - margin.left - margin.right - 2 * paddingLeftRight,
placeholderHeight = size.height - margin.top - margin.bottom - 2 * paddingTopBottom,
rowsColumnsData,
condition,
maxBBox = getMaxBBox(groups);
var moveRowsColumns = function(rows, columns) {
rowsColumnsData = that._getDataRowsColumns(groups, columns, rows);
that._moveItems(rowsColumnsData, groups, itemTextPosition, trackers, options)
};
moveRowsColumns(rows, columns);
legendBox = that._insideLegendGroup ? that._insideLegendGroup.getBBox() : {};
if (rowsColumns.autoEdit)
if (rows === 1) {
if (legendBox.width > placeholderWidth && columns > 1) {
columns = _floor(placeholderWidth / (maxBBox.width + options.columnItemSpacing)) || 1;
columns = validate(columns, count);
rows = _ceil(count / columns);
moveRowsColumns(rows, columns)
}
}
else if (columns === 1)
if (legendBox.height > placeholderHeight && rows > 1) {
rows = _floor(placeholderHeight / (maxBBox.height + options.rowItemSpacing)) || 1;
rows = validate(rows, count);
columns = _ceil(count / rows);
moveRowsColumns(rows, columns)
}
that._rowsCountDrawed = rows;
that._columnsCountDrawed = columns;
function validate(rowsOrColumns, count) {
if (rowsOrColumns > count || rowsOrColumns < 1)
rowsOrColumns = count;
return rowsOrColumns
}
},
_moveItems: function(data, seriesGroups, horizontalTextPosition, trackers, options) {
var that = this,
i,
j,
rows,
cols,
number,
group,
box,
xShift = 0,
yShift = 0,
widthColumn,
xPadding = options.columnItemSpacing,
yPadding = options.rowItemSpacing,
equalColumnWidth = options.equalColumnWidth,
renderer = that._renderer,
maxWidthPerColumn = [],
maxWidthColumn = 0,
maxHeightRow = 0;
rows = data.rows;
cols = data.cols;
maxHeightRow = data.maxHeightRow;
maxWidthColumn = data.maxWidthColumn;
maxWidthPerColumn = data.maxWidthPerColumn;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
if (rows < cols)
number = i * cols + j;
else
number = i + j * rows;
group = seriesGroups[number];
if (!group)
break;
box = group.getBBox();
widthColumn = !equalColumnWidth ? maxWidthPerColumn[j] : maxWidthColumn;
if (horizontalTextPosition === RIGHT) {
group.move(xShift - box.x, yShift);
trackers[number].rect.applySettings({
x: xShift - xPadding / 2,
y: yShift + box.y - yPadding / 2,
height: maxHeightRow + yPadding,
width: widthColumn + xPadding
})
}
else if (horizontalTextPosition === LEFT) {
group.move(box.x + widthColumn - box.width + xShift - xPadding / 2, yShift);
trackers[number].rect.applySettings({
x: box.x + widthColumn - box.width + xShift - xPadding / 2,
y: yShift + box.y - yPadding / 2,
height: maxHeightRow + yPadding,
width: widthColumn + xPadding
})
}
else {
group.move(xShift - box.x - box.width / 2 + widthColumn / 2, yShift);
trackers[number].rect.applySettings({
x: xShift - xPadding / 2,
y: yShift + box.y - yPadding / 2,
height: maxHeightRow + yPadding,
width: widthColumn + xPadding
})
}
xShift = xShift + widthColumn + xPadding
}
yShift = yShift + maxHeightRow + yPadding;
xShift = 0
}
},
_getDataRowsColumns: function(seriesGroups, cols, rows) {
var that = this,
i,
j,
options = that._options,
equalColumnWidth = options.equalColumnWidth,
series = that.series || {},
maxWidthPerColumn = [],
maxWidthColumn = 0,
maxHeightRow = 0,
group,
box;
for (i = 0; i < cols; i++)
maxWidthPerColumn[i] = 0;
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++) {
if (rows < cols)
group = seriesGroups[i * cols + j];
else
group = seriesGroups[i + j * rows];
if (!group)
break;
box = group.getBBox();
if (maxHeightRow < box.height)
maxHeightRow = box.height;
if (!equalColumnWidth) {
if (maxWidthPerColumn[j] < box.width)
maxWidthPerColumn[j] = box.width
}
else if (maxWidthColumn < box.width)
maxWidthColumn = box.width
}
return {
rows: rows,
cols: cols,
maxWidthPerColumn: maxWidthPerColumn,
maxWidthColumn: maxWidthColumn,
maxHeightRow: maxHeightRow
}
},
_getRowsColumns: function(count) {
var that = this,
options = that._options,
isHorizontal = options.orientation === HORIZONTAL,
rows = options.rowCount,
onRows = _ceil(count / rows),
columns = options.columnCount,
onColumns = _ceil(count / columns),
autoEdit;
if (columns && !rows)
rows = onColumns;
else if (!columns && rows)
columns = onRows;
else if (columns && rows) {
if (isHorizontal && columns < onRows)
columns = onRows;
else if (!isHorizontal && rows < onColumns)
rows = onColumns
}
else {
autoEdit = true;
if (isHorizontal) {
rows = 1;
columns = count
}
else {
columns = 1;
rows = count
}
}
return {
rows: rows,
columns: columns,
autoEdit: autoEdit
}
},
_adjustBackgroundSettings: function(background, borderVisible, options) {
var that = this,
border = options.border,
legendBox = that._insideLegendGroup.getBBox(),
backgroundSettings = {
x: _round(legendBox.x - options.paddingLeftRight),
y: _round(legendBox.y - options.paddingTopBottom),
width: _round(legendBox.width) + 2 * options.paddingLeftRight,
height: _round(legendBox.height) + 2 * options.paddingTopBottom,
opacity: options.backgroundOpacity
};
if (borderVisible) {
backgroundSettings.strokeWidth = border.width;
backgroundSettings.stroke = border.color;
backgroundSettings.strokeOpacity = border.opacity;
backgroundSettings.dashStyle = border.dashStyle;
backgroundSettings.rx = border.cornerRadius || 0;
backgroundSettings.ry = border.cornerRadius || 0
}
background.applySettings(backgroundSettings)
},
_setBoundingRect: function(options) {
var that = this,
box,
margin = options.margin;
if (!that._insideLegendGroup)
return;
box = that._insideLegendGroup.getBBox();
box.height += margin.top + margin.bottom;
box.width += margin.left + margin.right;
box.x -= margin.left;
box.y -= margin.top;
that.boundingRect = box
},
changeSize: function(size) {
var that = this,
options = $.extend(true, {}, that._options),
margin = options.margin;
if (size.height >= 0) {
size.height = decreaseGaps(margin, ["top", "bottom"], size.height);
if (options.border.visible)
size.height = 2 * decreaseGaps(options, ["paddingTopBottom"], size.height / 2);
if (that._rowsCountDrawed - 1)
size.height = (that._rowsCountDrawed - 1) * decreaseGaps(options, ["rowItemSpacing"], size.height / (that._rowsCountDrawed - 1))
}
if (size.width >= 0) {
size.width = decreaseGaps(margin, ["left", "right"], size.width);
if (options.border.visible)
size.width = 2 * decreaseGaps(options, ["paddingLeftRight"], size.width / 2);
if (that._columnsCountDrawed - 1)
size.width = (that._columnsCountDrawed - 1) * decreaseGaps(options, ["columnItemSpacing"], size.width / (that._columnsCountDrawed - 1))
}
if (that._insideLegendGroup)
if (size.height > 0 || size.width > 0) {
that._options._incidentOccured("W2104");
that._insideLegendGroup.remove();
that._insideLegendGroup = null;
that._trackerGroup && that._trackerGroup.clear()
}
else
that._locateElements(options)
},
getTrackerGroup: function() {
return this._trackerGroup
},
getActionCallback: function(point) {
var that = this;
if (that._options.visible)
return function(act) {
var pointType = point.type,
isSeries = pointType ? true : false,
seriesType = pointType || point.series.type;
if (isSeries || seriesType === 'pie' || seriesType === 'doughnut' || seriesType === 'donut')
that[act] && that[act](point.index)
};
else
return $.noop
},
getLayoutOptions: function() {
var options = this._options,
boundingRect = this._insideLegendGroup ? this.boundingRect : {
width: 0,
height: 0,
x: 0,
y: 0
};
if (options) {
boundingRect.verticalAlignment = options.verticalAlignment;
boundingRect.horizontalAlignment = options.horizontalAlignment;
if (options.orientation === 'horizontal')
boundingRect.cutLayoutSide = options.verticalAlignment;
else
boundingRect.cutLayoutSide = options.horizontalAlignment === 'center' ? options.verticalAlignment : options.horizontalAlignment;
return boundingRect
}
return null
},
shift: function(x, y) {
var that = this,
settings = {},
box = that.getLayoutOptions();
settings.translateX = x - box.x;
settings.translateY = y - box.y;
that._insideLegendGroup && that._insideLegendGroup.applySettings(settings);
that._trackerGroup && that._trackerGroup.applySettings(settings)
},
getPosition: function() {
return this._options.position
},
dispose: function() {
var that = this;
that._disposeTrackers();
that._legendGroup = null;
that._trackerGroup = null;
that._insideLegendGroup = null;
that._renderer = null;
that._options = null;
that._data = null;
return that
}
})
})(DevExpress, jQuery);
/*! Module viz-core, file range.js */
(function($, DX, undefined) {
var core = DX.viz.core,
utils = DX.utils,
isDefinedUtils = utils.isDefined,
isDateUtils = utils.isDate,
getLogUtils = utils.getLog,
raiseToUtils = utils.raiseTo;
var NUMBER_EQUALITY_CORRECTION = 1,
DATETIME_EQUALITY_CORRECTION = 60000;
var minSelector = 'min',
maxSelector = 'max',
minVisibleSelector = 'minVisible',
maxVisibleSelector = 'maxVisible',
minValueMarginSelector = 'minValueMargin',
maxValueMarginSelector = 'maxValueMargin',
categoriesSelector = 'categories',
keepValueMarginsSelector = 'keepValueMargins',
baseSelector = 'base',
axisTypeSelector = 'axisType';
var raiseToFlooredLog = function(value, base, correction) {
return raiseToUtils(Math.floor(getLogUtils(value, base)) + (correction || 0), base)
};
var otherLessThan = function(thisValue, otherValue) {
return otherValue < thisValue
};
var otherGreaterThan = function(thisValue, otherValue) {
return otherValue > thisValue
};
var compareAndReplace = function(thisValue, otherValue, setValue, compare) {
var otherValueDefined = isDefinedUtils(otherValue);
if (isDefinedUtils(thisValue)) {
if (otherValueDefined && compare(thisValue, otherValue))
setValue(otherValue)
}
else if (otherValueDefined)
setValue(otherValue)
};
var applyMargin = function(value, margin, rangeLength, coef, isDateTime) {
value = value.valueOf() + coef * rangeLength * margin;
return isDateTime ? new Date(value) : value
};
DX.viz.core.__NUMBER_EQUALITY_CORRECTION = NUMBER_EQUALITY_CORRECTION;
DX.viz.core.__DATETIME_EQUALITY_CORRECTION = DATETIME_EQUALITY_CORRECTION;
core.Range = function(range) {
range && $.extend(this, range)
};
$.extend(core.Range.prototype, {
dispose: function() {
this[categoriesSelector] = null
},
addRange: function(otherRange) {
var that = this,
categories = that[categoriesSelector],
categoriesValues,
otherCategories = otherRange[categoriesSelector],
i,
j,
length,
found;
var setIndentByPriority = function(prefix) {
var prioritySelector = prefix + 'Priority',
priorityRelation = (that[prioritySelector] || 0) - (otherRange[prioritySelector] || 0);
if ((that[prefix] || 0) < otherRange[prefix] && priorityRelation === 0 || priorityRelation < 0) {
that[prefix] = otherRange[prefix];
that[prioritySelector] = otherRange[prioritySelector]
}
};
var compareAndReplaceByField = function(field, compare) {
compareAndReplace(that[field], otherRange[field], function(value) {
that[field] = value
}, compare)
};
var controlValuesByVisibleBounds = function(valueField, visibleValueField, compare) {
compareAndReplace(that[valueField], that[visibleValueField], function(value) {
isDefinedUtils(that[valueField]) && (that[valueField] = value)
}, compare)
};
var checkField = function(field) {
that[field] = that[field] || otherRange[field]
};
if (utils.isDefined(otherRange["stick"]))
that["stick"] = otherRange["stick"];
checkField('invert');
checkField(axisTypeSelector);
checkField('dataType');
checkField(keepValueMarginsSelector);
if (that[axisTypeSelector] === 'logarithmic')
checkField(baseSelector);
else
that[baseSelector] = undefined;
compareAndReplaceByField(minSelector, otherLessThan);
compareAndReplaceByField(maxSelector, otherGreaterThan);
compareAndReplaceByField(minVisibleSelector, otherLessThan);
compareAndReplaceByField(maxVisibleSelector, otherGreaterThan);
compareAndReplaceByField('interval', otherLessThan);
setIndentByPriority(minValueMarginSelector);
setIndentByPriority(maxValueMarginSelector);
controlValuesByVisibleBounds(minSelector, minVisibleSelector, otherLessThan);
controlValuesByVisibleBounds(minSelector, maxVisibleSelector, otherLessThan);
controlValuesByVisibleBounds(maxSelector, maxVisibleSelector, otherGreaterThan);
controlValuesByVisibleBounds(maxSelector, minVisibleSelector, otherGreaterThan);
if (categories === undefined)
that[categoriesSelector] = otherCategories;
else {
length = categories.length;
if (otherCategories && otherCategories.length)
for (i = 0; i < otherCategories.length; i++) {
for (j = 0, found = false; j < length; j++)
if (categories[j].valueOf() === otherCategories[i].valueOf()) {
found = true;
break
}
!found && categories.push(otherCategories[i])
}
}
return this
},
isDefined: function() {
return isDefinedUtils(this[minSelector]) && isDefinedUtils(this[maxSelector]) || isDefinedUtils(this[categoriesSelector])
},
setStubData: function(dataType) {
var that = this,
year = (new Date).getYear() - 1,
isDate = dataType === 'datetime',
isCategories = that.axisType === 'discrete';
if (isCategories)
that.categories = ['0', '1', '2'];
else {
that[minSelector] = isDate ? new Date(year, 0, 1) : 0;
that[maxSelector] = isDate ? new Date(year, 11, 31) : 10
}
that.stubData = true;
return that
},
applyValueMargins: function() {
var that = this,
base = that[baseSelector],
isDateTime = isDateUtils(that[maxSelector]) || isDateUtils(that[minSelector]);
var applyMarginWithZeroCorrection = function(min, max, rangeLength) {
var minValue = that[min],
maxValue = that[max],
minMargin = that[minValueMarginSelector],
maxMargin = that[maxValueMarginSelector],
minCorrected = false,
maxCorrected = false;
if (rangeLength && !isDateTime && !that[keepValueMarginsSelector]) {
if (minValue <= 0 && maxValue <= 0 && maxMargin > maxValue / (minValue - maxValue)) {
that[max] = 0;
maxCorrected = true
}
if (minValue >= 0 && maxValue >= 0 && minMargin > minValue / (maxValue - minValue)) {
that[min] = 0;
minCorrected = true
}
}
if (isDefinedUtils(maxValue) && !maxCorrected && maxMargin)
that[max] = applyMargin(maxValue, maxMargin, rangeLength, 1, isDateTime);
if (isDefinedUtils(minValue) && !minCorrected && minMargin)
that[min] = applyMargin(minValue, minMargin, rangeLength, -1, isDateTime)
};
var correctValueByBoundaries = function(visibleSelector, valueSelector) {
that[visibleSelector] = isDefinedUtils(that[visibleSelector]) ? that[visibleSelector] : that[valueSelector]
};
var processLogarithmicMinValue = function(valueField) {
if (isDefinedUtils(that[valueField])) {
var intermediateValue = raiseToFlooredLog(that[valueField], base);
if (getLogUtils(that[valueField] / intermediateValue, base) < 0.1 && that.alwaysCorrectMin && !that[keepValueMarginsSelector])
that[valueField] = raiseToFlooredLog(that[valueField], base, -1);
else if (that.alwaysCorrectMin && !that[keepValueMarginsSelector])
that[valueField] = intermediateValue;
else if (getLogUtils(that[valueField] / intermediateValue, base) < 0.5)
that[valueField] = intermediateValue
}
};
var processLogarithmicMaxValue = function(valueField) {
if (isDefinedUtils(that[valueField])) {
var intermediateValue = raiseToFlooredLog(that[valueField], base);
if (getLogUtils(that[valueField] / intermediateValue, base) > 0.5)
that[valueField] = raiseToUtils(Math.ceil(getLogUtils(that[valueField], base)), base)
}
};
var correctLogVisibleValue = function(visibleValueSelector, valueSelector, compare) {
if (!isDefinedUtils(that[visibleValueSelector]) || compare)
that[visibleValueSelector] = that[valueSelector]
};
if (that[axisTypeSelector] === 'logarithmic' && that[minSelector] !== that[maxSelector]) {
processLogarithmicMinValue(minSelector);
processLogarithmicMaxValue(maxSelector);
if (that.isValueRange && that[minVisibleSelector] !== that[maxVisibleSelector]) {
processLogarithmicMinValue(minVisibleSelector);
processLogarithmicMaxValue(maxVisibleSelector)
}
correctLogVisibleValue(minVisibleSelector, minSelector, that[minVisibleSelector] < that[minSelector]);
correctLogVisibleValue(maxVisibleSelector, maxSelector, that[maxVisibleSelector] > that[maxSelector])
}
else {
correctValueByBoundaries(minVisibleSelector, minSelector);
correctValueByBoundaries(maxVisibleSelector, maxSelector);
applyMarginWithZeroCorrection(minSelector, maxSelector, that[maxSelector] - that[minSelector]);
applyMarginWithZeroCorrection(minVisibleSelector, maxVisibleSelector, that[maxVisibleSelector] - that[minVisibleSelector])
}
return this
},
correctValueZeroLevel: function() {
var that = this;
if (isDateUtils(that[maxSelector]) || isDateUtils(that[minSelector]))
return that;
function setZeroLevel(min, max) {
that[min] < 0 && that[max] < 0 && (that[max] = 0);
that[min] > 0 && that[max] > 0 && (that[min] = 0)
}
setZeroLevel(minSelector, maxSelector);
setZeroLevel(minVisibleSelector, maxVisibleSelector);
return that
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file seriesConsts.js */
(function(DX) {
DX.viz.core.series = DX.viz.core.series || {};
DX.viz.core.series.helpers = DX.viz.core.series.helpers || {};
DX.viz.core.series.helpers.consts = {
events: {
mouseover: "mouseover",
mouseout: "mouseout",
mousemove: "mousemove",
touchstart: "touchstart",
touchmove: "touchmove",
touchend: "touchend",
mousedown: "mousedown",
mouseup: "mouseup",
click: "click",
selectSeries: "selectseries",
deselectSeries: "deselectseries",
selectPoint: "selectpoint",
deselectPoint: "deselectpoint",
showPointTooltip: "showpointtooltip",
hidePointTooltip: "hidepointtooltip"
},
states: {
hover: "hover",
normal: "normal",
selected: "selected",
normalMark: 0,
hoverMark: 1,
selectedMark: 2
},
animations: {
showDuration: {duration: 400},
hideGroup: {opacity: 0.0001},
showGroup: {opacity: 1}
}
}
})(DevExpress);
/*! Module viz-core, file seriesFamily.js */
(function($, DX, undefined) {
var utils = DX.utils,
_round = Math.round,
_abs = Math.abs,
_pow = Math.pow;
DX.viz.core.series.helpers.SeriesFamily = DX.Class.inherit(function() {
var ctor = function(options) {
var debug = DX.utils.debug;
debug.assert(options.type, "type was not passed or empty");
var that = this,
stubFunction = $.noop;
$.extend(that, options);
that.type = that.type.toLowerCase();
that.series = [];
switch (that.type) {
case"bar":
that.adjustSeriesDimensions = adjustBarSeriesDimensions;
that.adjustSeriesValues = stubFunction;
that.updateSeriesValues = updateBarSeriesValues;
break;
case"rangebar":
that.adjustSeriesDimensions = adjustBarSeriesDimensions;
that.adjustSeriesValues = stubFunction;
that.updateSeriesValues = stubFunction;
break;
case"fullstackedbar":
that.fullStacked = true;
that.adjustSeriesDimensions = adjustStackedBarSeriesDimensions;
that.adjustSeriesValues = adjustStackedSeriesValues;
that.updateSeriesValues = updateStackedSeriesValues;
break;
case"stackedbar":
that.adjustSeriesDimensions = adjustStackedBarSeriesDimensions;
that.adjustSeriesValues = adjustStackedSeriesValues;
that.updateSeriesValues = updateStackedSeriesValues;
break;
case"fullstackedarea":
case"fullstackedline":
that.fullStacked = true;
that.adjustSeriesDimensions = stubFunction;
that.adjustSeriesValues = adjustStackedSeriesValues;
that.updateSeriesValues = stubFunction;
break;
case"stackedarea":
case"stackedline":
that.adjustSeriesDimensions = stubFunction;
that.adjustSeriesValues = adjustStackedSeriesValues;
that.updateSeriesValues = stubFunction;
break;
case"candlestick":
case"stock":
that.adjustSeriesDimensions = adjustCandlestickSeriesDimensions;
that.adjustSeriesValues = stubFunction;
that.updateSeriesValues = stubFunction;
break;
case"bubble":
that.adjustSeriesDimensions = adjustBubbleSeriesDimensions;
that.adjustSeriesValues = stubFunction;
that.updateSeriesValues = stubFunction;
break;
default:
that.adjustSeriesDimensions = stubFunction;
that.adjustSeriesValues = stubFunction;
that.updateSeriesValues = stubFunction;
break
}
};
var dispose = function() {
this.series = null;
this.translators = null
};
var add = function(series) {
var that = this,
singleSeries,
i;
if (!$.isArray(series))
series = [series];
for (i = 0; i < series.length; i++) {
singleSeries = series[i];
if (singleSeries.type.toLowerCase() === that.type)
that.series.push(singleSeries)
}
};
var adjustBarSeriesDimensionsCore = function(series, interval, stackCount, equalBarWidth, seriesStackIndexCallback) {
var spacing,
width,
maxWidth,
middleIndex,
stackIndex,
i,
point,
points,
seriesOffset,
stackName,
argumentsKeeper = {},
stackKeepers = {},
stacksWithArgument,
count;
if (equalBarWidth) {
width = equalBarWidth.width && equalBarWidth.width < 0 ? 0 : equalBarWidth.width;
spacing = equalBarWidth.spacing && equalBarWidth.spacing < 0 ? 0 : equalBarWidth.spacing;
if (width && !spacing)
if (stackCount > 1) {
spacing = _round((interval * 0.7 - width * stackCount) / (stackCount - 1));
if (spacing < 1)
spacing = 1
}
else
spacing = 0;
else if (spacing && !width) {
width = _round((interval * 0.7 - spacing * (stackCount - 1)) / stackCount);
if (width < 2)
width = 2
}
else if (!spacing && !width) {
if (stackCount > 1) {
spacing = _round(interval * 0.7 / stackCount * 0.2);
if (spacing < 1)
spacing = 1
}
else
spacing = 0;
width = _round((interval * 0.7 - spacing * (stackCount - 1)) / stackCount);
if (width < 2)
width = 2
}
if (width * stackCount + spacing * (stackCount - 1) > interval) {
spacing = _round((interval * 0.7 - width * stackCount) / (stackCount - 1));
if (spacing < 1) {
spacing = 1;
maxWidth = _round((interval * 0.7 - spacing * (stackCount - 1)) / stackCount)
}
}
middleIndex = stackCount / 2;
for (i = 0; i < series.length; i++) {
stackIndex = seriesStackIndexCallback(i);
points = series[i].getPoints();
seriesOffset = (stackIndex - middleIndex + 0.5) * (maxWidth || width) - (middleIndex - stackIndex - 0.5) * spacing;
$.each(points, function(_, point) {
point.correctCoordinates({
width: width,
offset: seriesOffset
})
})
}
}
else {
$.each(series, function(i, singleSeries) {
stackName = singleSeries.getStackName && singleSeries.getStackName();
stackName = stackName || i.toString();
if (!stackKeepers[stackName])
stackKeepers[stackName] = [];
stackKeepers[stackName].push(singleSeries)
});
$.each(series, function(i, singleSeries) {
$.each(singleSeries.getPoints(), function(_, point) {
var argument = point.argument;
if (!argumentsKeeper.hasOwnProperty(argument))
argumentsKeeper[argument.valueOf()] = 1
})
});
for (var argument in argumentsKeeper) {
if (!argumentsKeeper.hasOwnProperty(argument))
continue;
stacksWithArgument = [];
$.each(stackKeepers, function(stackName, seriesInStack) {
$.each(seriesInStack, function(i, singleSeries) {
point = singleSeries.getPointByArg(argument);
if (point && point.value) {
stacksWithArgument.push(stackName);
return false
}
})
});
count = stacksWithArgument.length;
spacing = _round(interval * 0.7 / count * 0.2);
if (spacing < 1)
spacing = 1;
width = _round((interval * 0.7 - spacing * (count - 1)) / count);
if (width < 2)
width = 2;
middleIndex = count / 2;
$.each(stackKeepers, function(stackName, seriesInStack) {
stackIndex = $.inArray(stackName, stacksWithArgument);
if (stackIndex === -1)
return;
seriesOffset = (stackIndex - middleIndex + 0.5) * width - (middleIndex - stackIndex - 0.5) * spacing;
$.each(seriesInStack, function(i, singleSeries) {
var point = singleSeries.getPointByArg(argument);
if (point && point.value)
point.correctCoordinates({
width: width,
offset: seriesOffset
})
})
})
}
}
};
var getVisibleSeries = function(that) {
return $.map(that.series, function(s) {
return s.isVisible() ? s : null
})
};
var adjustBarSeriesDimensions = function(translators) {
var debug = DX.utils.debug;
debug.assert(translators, "translator was not passed or empty");
var that = this,
equalBarWidth = that.equalBarWidth,
series = getVisibleSeries(that);
adjustBarSeriesDimensionsCore(series, getInterval(that, translators), series.length, equalBarWidth, function(seriesIndex) {
return seriesIndex
})
};
var adjustStackedBarSeriesDimensions = function(translators) {
var debug = DX.utils.debug;
debug.assert(translators, "translators was not passed or empty");
var that = this,
interval,
series = getVisibleSeries(that),
stackIndexes = {},
stackCount = 0,
equalBarWidth = that.equalBarWidth;
$.each(series, function() {
var stackName = this.getStackName();
if (!stackIndexes.hasOwnProperty(stackName))
stackIndexes[stackName] = stackCount++
});
adjustBarSeriesDimensionsCore(series, getInterval(that, translators), stackCount, equalBarWidth, function(seriesIndex) {
return stackIndexes[series[seriesIndex].getStackName()]
})
};
var adjustStackedSeriesValues = function() {
var that = this,
series = getVisibleSeries(that),
stackKeepers = {
positive: {},
negative: {}
};
$.each(series, function(_, singleSeries) {
var points = singleSeries.getPoints();
$.each(points, function(index, point) {
var value = point.initialValue,
argument = point.argument,
stackName = singleSeries.getStackName ? singleSeries.getStackName() : "default",
valueType = value >= 0 ? "positive" : "negative",
currentStack;
stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};
currentStack = stackKeepers[valueType][stackName];
if (currentStack[argument.valueOf()]) {
points[index].correctValue(currentStack[argument.valueOf()]);
currentStack[argument.valueOf()] += value
}
else {
currentStack[argument.valueOf()] = value;
points[index].resetCorrection()
}
})
});
setPercentStackedValues(series, stackKeepers, that.fullStacked)
};
var setPercentStackedValues = function(series, stackKeepers, fullStacked) {
$.each(series, function(_, singleSeries) {
var points = singleSeries.getPoints();
$.each(points, function(index, point) {
var value = point.value,
stackName = singleSeries.getStackName ? singleSeries.getStackName() : "default",
valueType = value >= 0 ? "positive" : "negative",
currentStack;
stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};
currentStack = stackKeepers[valueType][stackName];
points[index].setPercentValue(currentStack[point.argument.valueOf()], fullStacked)
})
})
};
var getMinShownBusinessValue = function(that, translators, minBarSize) {
var rotated = that.rotated,
valTranslator = rotated ? translators.x : translators.y,
canvas = valTranslator.getCanvasVisibleArea();
if (minBarSize)
return _abs(valTranslator.untranslate(canvas.min) - valTranslator.untranslate(canvas.min + minBarSize))
};
var updateStackedSeriesValues = function(translators) {
var that = this,
series = getVisibleSeries(that),
stackKeepers = {
positive: {},
negative: {}
};
$.each(series, function(_, singleSeries) {
var points = singleSeries.getPoints(),
minBarSize = singleSeries.getOptions().minBarSize;
$.each(points, function(index, point) {
var value = point.value,
minValue = point.minValue,
argument = point.argument,
updateValue,
pointSize,
minShownBusinessValue,
stackName = singleSeries.getStackName ? singleSeries.getStackName() : "default",
valueType = value >= 0 ? "positive" : "negative",
currentStack;
minShownBusinessValue = getMinShownBusinessValue(that, translators, minBarSize);
currentStack = stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};
if (currentStack[argument.valueOf()]) {
minValue = utils.isNumber(minValue) ? minValue : 0,
pointSize = _abs(minValue - value);
if (minShownBusinessValue && pointSize < minShownBusinessValue)
updateValue = minShownBusinessValue;
else
updateValue = value - minValue;
points[index].minValue = currentStack[argument.valueOf()];
points[index].value = currentStack[argument.valueOf()] + updateValue;
currentStack[argument.valueOf()] += updateValue
}
else {
pointSize = value;
if (minShownBusinessValue && pointSize < minShownBusinessValue)
updateValue = minShownBusinessValue;
else
updateValue = value;
points[index].value = updateValue;
currentStack[argument.valueOf()] = updateValue
}
})
});
if (that.fullStacked)
updateFullStackedSeriesValues(series, stackKeepers)
};
var updateFullStackedSeriesValues = function(series, stackKeepers) {
$.each(series, function(_, singleSeries) {
var stackName = singleSeries.getStackName ? singleSeries.getStackName() : "default",
points = singleSeries.getPoints();
$.each(points, function(index, point) {
var value = point.value,
argument = point.argument,
valueType = value >= 0 ? "positive" : "negative",
currentStack;
stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};
currentStack = stackKeepers[valueType][stackName];
points[index].value = points[index].value / currentStack[argument.valueOf()] || 0;
if (DX.utils.isNumber(points[index].minValue))
points[index].minValue = points[index].minValue / currentStack[argument.valueOf()] || 0
})
})
};
var updateBarSeriesValues = function(translators) {
var that = this;
$.each(that.series, function(_, singleSeries) {
var points = singleSeries.getPoints(),
minBarSize = singleSeries.getOptions().minBarSize;
$.each(points, function(index, point) {
var value = point.value,
updateValue,
pointSize,
minShownBusinessValue;
minShownBusinessValue = getMinShownBusinessValue(that, translators, minBarSize);
pointSize = _abs(value);
if (minShownBusinessValue && pointSize < minShownBusinessValue)
updateValue = value >= 0 ? minShownBusinessValue : -minShownBusinessValue;
else
updateValue = value;
points[index].value = updateValue
})
})
};
var adjustCandlestickSeriesDimensions = function(translators) {
var debug = DX.utils.debug;
debug.assert(translators, "translator was not passed or empty");
var that = this,
series = getVisibleSeries(that);
adjustBarSeriesDimensionsCore(series, getInterval(that, translators), series.length, true, function(seriesIndex) {
return seriesIndex
})
};
var getInterval = function(that, translators) {
var argTranslator = !that.rotated ? translators.x : translators.y;
return that.interval = argTranslator.getInterval()
};
var adjustBubbleSeriesDimensions = function(translators) {
var debug = DX.utils.debug;
debug.assert(translators, "translator was not passed or empty");
var that = this,
series = getVisibleSeries(that),
points,
i,
visibleAreaX = translators.x.getCanvasVisibleArea(),
visibleAreaY = translators.y.getCanvasVisibleArea(),
min = Math.min(visibleAreaX.max - visibleAreaX.min, visibleAreaY.max - visibleAreaY.min),
minBubbleArea = _pow(that.minBubbleSize, 2),
maxBubbleArea = _pow(min * that.maxBubbleSize, 2),
equalBubbleSize = (min * that.maxBubbleSize + that.minBubbleSize) / 2,
minPointSize = Infinity,
maxPointSize = 0,
pointSize,
bubbleArea,
sizeProportion,
sizeDispersion,
areaDispersion;
for (i = 0; i < series.length; i++) {
points = series[i].getPoints();
$.each(points, function(_, point) {
maxPointSize = maxPointSize > point.size ? maxPointSize : point.size;
minPointSize = minPointSize < point.size ? minPointSize : point.size
})
}
sizeDispersion = maxPointSize - minPointSize;
areaDispersion = _abs(maxBubbleArea - minBubbleArea);
minPointSize = minPointSize < 0 ? 0 : minPointSize;
for (i = 0; i < series.length; i++) {
points = series[i].getPoints();
$.each(points, function(_, point) {
if (maxPointSize === minPointSize)
pointSize = _round(equalBubbleSize);
else {
sizeProportion = _abs(point.size - minPointSize) / sizeDispersion;
bubbleArea = areaDispersion * sizeProportion + minBubbleArea;
pointSize = _round(Math.sqrt(bubbleArea))
}
point.correctCoordinates(pointSize)
})
}
};
return {
ctor: ctor,
dispose: dispose,
add: add
}
}())
})(jQuery, DevExpress);
/*! Module viz-core, file baseSeries.js */
(function($, DX) {
var viz = DX.viz,
utils = DX.utils,
_isDefined = utils.isDefined,
_each = $.each,
_extend = $.extend,
_isEmptyObject = $.isEmptyObject,
_Event = $.Event,
_noop = $.noop,
SELECTED_STATE = 2,
HOVER_STATE = 1,
NONE_MODE = "none",
INCLUDE_POINTS = "includepoints",
EXLUDE_POINTS = "excludepoints",
ALL_SERIES_POINTS_MODE = "allseriespoints",
APPLY_SELECTED = "applySelected",
APPLY_HOVER = "applyHover",
getEmptyBusinessRange = function() {
return {
arg: {},
val: {}
}
};
viz.core.series.mixins = {
chart: {},
pieChart: {}
};
viz.core.series.Series = DX.Class.inherit({
ctor: function(renderer, options) {
this.fullState = 0;
this._renderer = renderer;
this._group = renderer.createGroup({"class": "dxc-series"});
this.updateOptions(options)
},
update: function(data, options) {
this.updateOptions(options);
this.updateData(data)
},
_createLegendState: function(styleOptions, defaultColor) {
return {
fill: styleOptions.color || defaultColor,
hatching: styleOptions.hatching
}
},
getLegendStyles: function() {
return this._styles.legendStyles
},
_createStyles: function(options) {
var mainSeriesColor = options.mainSeriesColor,
specialMainColor = this._getSpecialColor(mainSeriesColor);
this._styles = {
normal: this._parseStyle(options, mainSeriesColor, mainSeriesColor),
hover: this._parseStyle(options.hoverStyle || {}, specialMainColor, mainSeriesColor),
selection: this._parseStyle(options.selectionStyle || {}, specialMainColor, mainSeriesColor),
legendStyles: {
normal: this._createLegendState(options, mainSeriesColor),
hover: this._createLegendState(options.hoverStyle || {}, specialMainColor),
selection: this._createLegendState(options.selectionStyle || {}, specialMainColor)
}
}
},
setAdjustSeriesLabels: function(adjustSeriesLabels) {
_each(this._points || [], function(_, point) {
point.setAdjustSeriesLabels(adjustSeriesLabels)
})
},
setClippingParams: function(id, forceClipping) {
this._paneClipRectID = id;
this._forceClipping = forceClipping
},
getTagField: function() {
return this._options.tagField || "tag"
},
getValueFields: _noop,
getArgumentField: _noop,
getPoints: function() {
return this._points
},
_createPoint: function(data, pointsArray, index) {
data.index = index;
if (this._checkData(data)) {
var point = pointsArray[index],
options = this._customizePoint(data) || this._getCreatingPointOptions();
if (point)
point.update(data, options);
else {
point = viz.core.CoreFactory.createPoint(data, options);
pointsArray.push(point)
}
this.pointsByArgument[point.argument.valueOf()] = this.pointsByArgument[point.argument.valueOf()] || point;
return true
}
},
getRangeData: function(zoomArgs, calcIntervalFunction) {
return this._visible ? _extend(true, {}, this._getRangeData(zoomArgs, calcIntervalFunction)) : getEmptyBusinessRange()
},
_deleteElementsGroup: function() {
if (this._elementsGroup) {
this._elementsGroup.detach();
this._elementsGroup = null
}
},
_deleteBordersGroup: function() {
if (this._bordersGroup) {
this._bordersGroup.detach();
this._bordersGroup = null
}
},
_saveOldAnimationMethods: function() {
this._oldClearingAnimation = this._clearingAnimation;
this._oldUpdateElement = this._updateElement
},
_deleteOldAnimationMethods: function() {
this._oldClearingAnimation = null;
this._oldUpdateElement = null
},
updateOptions: function(newOptions) {
var that = this,
widgetType = newOptions.widgetType,
oldType = that.type,
newType = newOptions.type;
that.type = newType && newType.toString().toLowerCase();
if (!that._checkType(widgetType)) {
that.dispose();
that.isUpdated = false;
return
}
if (oldType !== that.type) {
that._firstDrawing = true;
that._saveOldAnimationMethods();
that._resetType(oldType, widgetType);
that._setType(that.type, widgetType)
}
that._options = newOptions;
that._pointOptions = null;
that._deletePatterns();
that._patterns = [];
that.name = newOptions.name;
that.pane = newOptions.pane;
that.axis = newOptions.axis;
that.tag = newOptions.tag;
that._createStyles(newOptions);
that._updateOptions(newOptions);
that._visible = newOptions.visible;
that.isUpdated = true
},
_disposePoints: function(points) {
$.each(points || [], function(_, p) {
p.dispose()
})
},
_correctPointsLength: function(length, points) {
this._disposePoints(this._oldPoints);
this._oldPoints = points.splice(length, points.length)
},
_getTicksForAggregation: function(min, max, screenDelta, pointSize) {
return viz.core.tickProvider.getTicks({
min: min,
max: max,
screenDelta: screenDelta,
gridSpacingFactor: pointSize
})
},
updateDataType: function(settings) {
var that = this;
that.argumentType = settings.argumentType;
that.valueType = settings.valueType;
that.argumentAxisType = settings.argumentAxisType;
that.valueAxisType = settings.valueAxisType
},
getValueCategories: function() {
return this._options.valueCategories || []
},
getOptions: function() {
return this._options
},
getArgumentCategories: function() {
return this._options.argumentCategories || []
},
updateData: function(data) {
var that = this,
points,
lastPointIndex = 0,
options = that._options,
pointData;
that.pointsByArgument = {};
points = that._originalPoints || [];
that._rangeData = getEmptyBusinessRange();
if (data && data.length)
that._canRenderCompleteHandle = true;
that._beginUpdateData();
_each(data, function(index, dataItem) {
pointData = that._getPointData(dataItem, options);
if (that._createPoint(pointData, points, lastPointIndex)) {
that._processRange(points[lastPointIndex], lastPointIndex > 0 ? points[lastPointIndex - 1] : null);
lastPointIndex++
}
});
that._points = that._originalPoints = points;
that._correctPointsLength(lastPointIndex, points);
that._endUpdateData()
},
getTeamplatedFields: function() {
var that = this,
fields = that.getValueFields(),
teampleteFields = [];
fields.push(that.getTagField());
_each(fields, function(_, field) {
var fieldsObject = {};
fieldsObject.teamplateField = field + that.name;
fieldsObject.originalField = field;
teampleteFields.push(fieldsObject)
});
return teampleteFields
},
resamplePoints: function(translators, min, max) {
var that = this,
originalPoints = that.getAllPoints(),
argTranslator = that._options.rotated ? translators.y : translators.x,
minI,
maxI,
sizePoint,
ticks;
if (originalPoints.length) {
_each(originalPoints, function(i, point) {
minI = point.argument - min <= 0 ? i : minI;
if (!maxI)
maxI = point.argument - max > 0 ? i : null
});
minI = minI ? minI : 1;
maxI = utils.isDefined(maxI) ? maxI : originalPoints.length - 1;
min = originalPoints[minI - 1].argument;
max = originalPoints[maxI].argument;
sizePoint = that._getPointSize();
if (that.argumentAxisType !== "discrete" && that.valueAxisType !== "discrete")
ticks = that._getTicksForAggregation(min, max, argTranslator.canvasLength, sizePoint);
else
ticks = argTranslator.canvasLength / sizePoint;
that._points = that._resample(ticks, ticks.tickInterval)
}
},
_removeOldSegments: function(startIndex) {
var that = this;
_each(that._graphics.splice(startIndex, that._graphics.length) || [], function(_, elem) {
that._removeElement(elem)
});
if (that._trackers)
_each(that._trackers.splice(startIndex, that._trackers.length) || [], function(_, elem) {
elem.remove()
})
},
draw: function(translators, animationEnabled, hideLayoutLabels, legendCallback) {
var that = this;
if (that._oldClearingAnimation && animationEnabled && that._firstDrawing) {
var drawComplete = function() {
that._draw(translators, true, hideLayoutLabels)
};
that._oldClearingAnimation(translators, drawComplete)
}
else
that._draw(translators, animationEnabled, hideLayoutLabels, legendCallback)
},
_clearSeries: function() {
this._deleteElementsGroup();
this._deleteBordersGroup();
this._deleteTrackers();
this._graphics = [];
this._trackers = []
},
_draw: function(translators, animationEnabled, hideLayoutLabels, legendCallback) {
var that = this,
points = that._points || [],
segment = [],
segmentCount = 0,
firstDrawing = that._firstDrawing,
markersGroup,
labelsGroup;
that._graphics = that._graphics || [],
that._graphics = that._graphics || [];
that._prepareSeriesToDrawing();
if (!that._visible) {
animationEnabled = false;
this._group.detach();
return
}
else
that._group.append(that._options.seriesGroup);
that.translators = translators;
that._createGroups(animationEnabled, undefined, firstDrawing);
that._segments = [];
markersGroup = that._markersGroup;
labelsGroup = that._labelsGroup;
that._drawedPoints = [];
that._firstDrawing = points.length ? false : true;
_each(this._patterns || [], function(_, pattern) {
pattern.append()
});
_each(points, function(i, p) {
p.translate(translators);
if (p.hasValue()) {
that._drawPoint(p, markersGroup, labelsGroup, animationEnabled, firstDrawing);
segment.push(p)
}
else if (segment.length) {
that._drawSegment(segment, animationEnabled, segmentCount++);
segment = []
}
});
segment.length && that._drawSegment(segment, animationEnabled, segmentCount++);
that._removeOldSegments(segmentCount);
that._defaultSegments = that._generateDefaultSegments();
that._adjustLabels(firstDrawing);
hideLayoutLabels && that.hideLabels();
animationEnabled && that._animate(firstDrawing);
if (that.isSelected())
that._changeStyle(legendCallback, APPLY_SELECTED);
else if (this.isHovered())
this._changeStyle(legendCallback, APPLY_HOVER)
},
drawTrackers: function() {
var that = this,
trackers = that._trackers = that._trackers || [],
trackersGroup = that._trackersGroup = that._trackersGroup || that._renderer.createGroup(),
markerTrackerGroup = that._markerTrackerGroup = that._markerTrackerGroup || that._renderer.createGroup();
if (!that.isVisible()) {
trackersGroup.detach();
markerTrackerGroup.detach();
return
}
else {
trackersGroup.append(that._options.trackersGroup);
markerTrackerGroup.append(that._options.markerTrackerGroup)
}
_each(that._segments || [], function(i, segment) {
if (!trackers[i]) {
trackers[i] = that._drawTrackerElement(segment).append(trackersGroup);
trackers[i].data({series: that})
}
else
that._updateTrackerElement(segment, trackers[i])
});
_each(that.getVisiblePoints(), function(_, p) {
p.drawTracker(that._renderer, markerTrackerGroup)
});
that._applyTrackersClippings()
},
_checkType: function(widgetType) {
return !!viz.core.series.mixins[widgetType][this.type]
},
_resetType: function(seriesType, widgetType) {
var that = this;
if (seriesType)
_each(viz.core.series.mixins[widgetType][seriesType], function(methodName) {
delete that[methodName]
})
},
_setType: function(seriesType, widgetType) {
var that = this;
_each(viz.core.series.mixins[widgetType][seriesType], function(methodName, method) {
that[methodName] = method
})
},
_setSelectedState: function(state, mode, legendCallback) {
this.lastSelectionMode = mode = (mode || this._options.selectionMode).toLowerCase();
if (state && !this.isSelected()) {
this.fullState = this.fullState | SELECTED_STATE;
this._changeStyle(legendCallback, APPLY_SELECTED)
}
else if (!state && this.isSelected()) {
this.fullState = this.fullState & ~SELECTED_STATE;
if (this.isHovered())
this._changeStyle(legendCallback, APPLY_HOVER);
else
this._changeStyle(legendCallback, "resetItem")
}
},
_setHoverState: function(state, mode, legendCallback) {
this.lastHoverMode = mode = (mode || this._options.hoverMode).toLowerCase();
if (state && !this.isHovered()) {
this.fullState = this.fullState | HOVER_STATE;
!this.isSelected() && this._changeStyle(legendCallback, APPLY_HOVER)
}
else if (!state && this.isHovered()) {
this.fullState = this.fullState & ~HOVER_STATE;
!this.isSelected() && this._changeStyle(legendCallback, "resetItem")
}
},
setHoverState: function(mode, legendCallback) {
this._setHoverState(true, mode, legendCallback)
},
releaseHoverState: function(mode, legendCallback) {
this._setHoverState(false, mode, legendCallback)
},
setSelectedState: function(mode, legendCallback) {
this._setSelectedState(true, mode, legendCallback)
},
releaseSelectedState: function(mode, legendCallback) {
this._setSelectedState(false, mode, legendCallback)
},
isFullStackedSeries: function() {
return this.type.indexOf("fullstacked") === 0
},
isStackedSeries: function() {
return this.type.indexOf("stacked") === 0
},
isFinancialSeries: function() {
return this.type === "stock" || this.type === "candlestick"
},
_changeStyle: function(legendCallBack, legendAction) {
var style = this._calcStyle(),
pointStyle;
if (style.mode === NONE_MODE)
return;
legendCallBack && legendCallBack(legendAction);
if (style.mode === INCLUDE_POINTS || style.mode === ALL_SERIES_POINTS_MODE) {
pointStyle = style.pointStyle;
_each(this._points || [], function(_, p) {
!p.isSelected() && p.applyStyle(pointStyle)
})
}
this._applyStyle(style.series)
},
_calcStyle: function() {
var styles = this._styles,
isHoverIncludeModeAndSeriesExcludeMode = false,
result;
switch (this.fullState & 3) {
case 0:
result = {
pointStyle: "normal",
mode: INCLUDE_POINTS,
series: styles.normal
};
break;
case 1:
result = {
pointStyle: "hover",
mode: this.lastHoverMode,
series: styles.hover
};
break;
case 2:
result = {
pointStyle: "selection",
mode: this.lastSelectionMode,
series: styles.selection
};
break;
case 3:
isHoverIncludeModeAndSeriesExcludeMode = this.lastSelectionMode === EXLUDE_POINTS && (this.lastHoverMode === INCLUDE_POINTS || this.lastHoverMode === ALL_SERIES_POINTS_MODE);
result = {
pointStyle: isHoverIncludeModeAndSeriesExcludeMode ? "normal" : "selection",
mode: isHoverIncludeModeAndSeriesExcludeMode ? INCLUDE_POINTS : this.lastSelectionMode,
series: styles.selection
}
}
return result
},
_getMainAxisName: function() {
return this._options.rotated ? "X" : "Y"
},
areLabelsVisible: function() {
return !_isDefined(this._options.maxLabelCount) || this._points.length <= this._options.maxLabelCount
},
getLabelVisibility: function() {
return this.areLabelsVisible() && this._options.label && this._options.label.visible
},
_customizePoint: function(pointData) {
var that = this,
options = that._options,
customizePoint = that._options.customizePoint,
customizeObject,
pointOptions,
customLabelOptions,
customOptions,
customizeLabel = that._options.customizeLabel,
useLabelCustomOptions,
usePointCustomOptions;
if (customizeLabel && customizeLabel.call) {
customizeObject = _extend({
seriesName: that.name,
series: that
}, pointData);
customLabelOptions = customizeLabel.call(customizeObject, customizeObject);
useLabelCustomOptions = customLabelOptions && !_isEmptyObject(customLabelOptions);
customLabelOptions = useLabelCustomOptions ? _extend(true, {}, options.label, customLabelOptions) : null
}
if (customizePoint && customizePoint.call) {
customizeObject = customizeObject || _extend({
seriesName: that.name,
series: that
}, pointData);
customOptions = customizePoint.call(customizeObject, customizeObject);
usePointCustomOptions = customOptions && !_isEmptyObject(customOptions)
}
if (useLabelCustomOptions || usePointCustomOptions) {
pointOptions = that._parsePointOptions(that._preparePointOptions(customOptions), customLabelOptions || options.label);
pointOptions.styles.useLabelCustomOptions = useLabelCustomOptions;
pointOptions.styles.usePointCustomOptions = usePointCustomOptions
}
return pointOptions
},
_getLabelOptions: function(labelOptions, defaultColor) {
var opt = labelOptions || {},
labelFont = opt.font || {},
labelBorder = opt.border || {},
labelConnector = opt.connector || {},
labelAttributes = {
align: opt.alignment,
font: {
color: opt.backgroundColor === "none" && labelFont.color.toLowerCase() === "#ffffff" && opt.position !== "inside" ? defaultColor : labelFont.color,
family: labelFont.family,
weight: labelFont.weight,
size: labelFont.size,
opacity: labelFont.opacity
},
style: opt.style
},
backgroundAttr = {
fill: opt.backgroundColor || defaultColor,
strokeWidth: labelBorder.visible ? labelBorder.width || 0 : 0,
stroke: labelBorder.visible && labelBorder.width ? labelBorder.color : "none",
dashStyle: labelBorder.dashStyle
},
connectorAttr = {
stroke: labelConnector.visible && labelConnector.width ? labelConnector.color || defaultColor : "none",
strokeWidth: labelConnector.visible ? labelConnector.width || 0 : 0
};
return {
format: opt.format,
argumentFormat: opt.argumentFormat,
precision: opt.precision,
argumentPrecision: opt.argumentPrecision,
percentPrecision: opt.percentPrecision,
customizeText: $.isFunction(opt.customizeText) ? opt.customizeText : undefined,
attributes: labelAttributes,
visible: labelFont.size !== 0 ? opt.visible : false,
showForZeroValues: opt.showForZeroValues,
horizontalOffset: opt.horizontalOffset,
verticalOffset: opt.verticalOffset,
radialOffset: opt.radialOffset,
background: backgroundAttr,
position: opt.position,
connector: connectorAttr,
rotationAngle: opt.rotationAngle,
resolveLabelsOverlapping: this._options.resolveLabelsOverlapping
}
},
show: function() {
if (!this._visible) {
this._visible = true;
this.hidePointTooltip();
this._options.visibilityChanged()
}
},
hide: function() {
if (this._visible) {
this._visible = false;
this.hidePointTooltip();
this._options.visibilityChanged()
}
},
hideLabels: function() {
_each(this._points, function(_, point) {
point._label.hide()
})
},
_parsePointOptions: function(pointOptions, labelOptions) {
var options = this._options,
styles = this._createPointStyles(pointOptions),
parsedOptions;
parsedOptions = _extend(true, {}, pointOptions, {
type: options.type,
tag: this.tag,
rotated: options.rotated,
series: this,
styles: styles,
visibilityChanged: options.visibilityChanged
});
parsedOptions.label = this._getLabelOptions(labelOptions, styles.normal.fill);
return parsedOptions
},
_resample: function(ticks, ticksInterval) {
var that = this,
fusPoints = [],
arrayFusPoints,
nowIndexTicks = 0,
lastPointIndex = 0,
originalPoints = that.getAllPoints();
if (that.argumentAxisType === "discrete" || that.valueAxisType === "discrete") {
ticksInterval = originalPoints.length / ticks;
arrayFusPoints = $.map(originalPoints, function(point, index) {
if (Math.floor(nowIndexTicks) <= index) {
nowIndexTicks += ticksInterval;
return point
}
point.setInvisibility();
return null
});
return arrayFusPoints
}
that._aggregatedPoints = that._aggregatedPoints || [];
_each(originalPoints, function(_, point) {
switch (that._isInInterval(point.argument, ticks, nowIndexTicks, ticksInterval)) {
case true:
fusPoints.push(point);
break;
case"nextInterval":
var pointData = that._fusionPoints(fusPoints, ticks[nowIndexTicks], nowIndexTicks);
while (that._isInInterval(point.argument, ticks, nowIndexTicks, ticksInterval) === "nextInterval")
nowIndexTicks++;
fusPoints = [];
that._isInInterval(point.argument, ticks, nowIndexTicks, ticksInterval) === true && fusPoints.push(point);
if (that._createPoint(pointData, that._aggregatedPoints, lastPointIndex))
lastPointIndex++
}
});
if (fusPoints.length) {
var pointData = that._fusionPoints(fusPoints, ticks[nowIndexTicks], nowIndexTicks);
if (that._createPoint(pointData, that._aggregatedPoints, lastPointIndex))
lastPointIndex++
}
that._correctPointsLength(lastPointIndex, that._aggregatedPoints);
that._endUpdateData();
return that._aggregatedPoints
},
_isInInterval: function(argument, ticks, nowIndexTicks, ticksInterval) {
var minTick = ticks[nowIndexTicks],
maxTick = ticks[nowIndexTicks + 1],
sumMinTickTicksInterval;
ticksInterval = $.isNumeric(ticksInterval) ? ticksInterval : utils.convertDateTickIntervalToMilliseconds(ticksInterval);
sumMinTickTicksInterval = utils.isDate(minTick) ? new Date(minTick.getTime() + ticksInterval) : minTick + ticksInterval;
if (argument >= minTick && argument < sumMinTickTicksInterval)
return true;
if (argument < minTick || maxTick === undefined)
return false;
return "nextInterval"
},
canRenderCompleteHandle: function() {
var result = this._canRenderCompleteHandle;
delete this._canRenderCompleteHandle;
return !!result
},
isHovered: function() {
return !!(this.fullState & 1)
},
isSelected: function() {
return !!(this.fullState & 2)
},
isVisible: function() {
return this._visible
},
getAllPoints: function() {
return (this._originalPoints || []).slice()
},
getPointByPos: function(pos) {
return (this._points || [])[pos]
},
getVisiblePoints: function() {
return (this._drawedPoints || []).slice()
},
setPointHoverState: function(point, legendCallback) {
point.fullState = point.fullState | HOVER_STATE;
if (!(this.isSelected() && (this.lastSelectionMode === ALL_SERIES_POINTS_MODE || this.lastSelectionMode === INCLUDE_POINTS)) && !point.isSelected()) {
point.applyStyle("hover");
legendCallback && legendCallback("applyHover")
}
},
releasePointHoverState: function(point, legendCallback) {
point.fullState = point.fullState & ~HOVER_STATE;
if (!(this.isSelected() && (this.lastSelectionMode === ALL_SERIES_POINTS_MODE || this.lastSelectionMode === INCLUDE_POINTS)) && !point.isSelected())
if (!(this.isHovered() && (this.lastHoverMode === ALL_SERIES_POINTS_MODE || this.lastHoverMode === INCLUDE_POINTS))) {
point.applyStyle("normal");
legendCallback && legendCallback("resetItem")
}
},
setPointSelectedState: function(point, legendCallback) {
point.fullState = point.fullState | SELECTED_STATE;
point.applyStyle("selection");
legendCallback && legendCallback("applySelected")
},
releasePointSelectedState: function(point, legendCallback) {
point.fullState = point.fullState & ~SELECTED_STATE;
if (this.isHovered() && (this.lastHoverMode === ALL_SERIES_POINTS_MODE || this.lastHoverMode === INCLUDE_POINTS) || point.isHovered()) {
point.applyStyle("hover");
legendCallback && legendCallback("applyHover")
}
else if (this.isSelected() && (this.lastSelectionMode === ALL_SERIES_POINTS_MODE || this.lastSelectionMode === INCLUDE_POINTS)) {
point.applyStyle("selection");
legendCallback && legendCallback("applySelected")
}
else {
point.applyStyle("normal");
legendCallback && legendCallback("resetItem")
}
},
selectPoint: function(point) {
this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("selectpoint"), point)
},
deselectPoint: function(point) {
this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("deselectpoint"), point)
},
showPointTooltip: function(point) {
this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("showpointtooltip"), point)
},
hidePointTooltip: function(point) {
this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("hidepointtooltip"), point)
},
select: function() {
this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("selectseries", {target: this}), this._options.selectionMode);
this._group.toForeground();
this._trackersGroup && this._trackersGroup.toBackground()
},
clearSelection: function clearSelection() {
this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("deselectseries", {target: this}), this._options.selectionMode)
},
getPointByArg: function(arg) {
return this.pointsByArgument[arg.valueOf()] || null
},
_deletePoints: function() {
this._disposePoints(this._originalPoints);
this._disposePoints(this._aggregatedPoints);
this._disposePoints(this._oldPoints);
this._points = null;
this._oldPoints = null;
this._aggregatedPoints = null;
this._originalPoints = null;
this._drawedPoint = null
},
_deletePatterns: function() {
_each(this._patterns || [], function(_, pattern) {
pattern && pattern.dispose()
});
this._patterns = null
},
_deleteTrackers: function() {
var that = this;
_each(that._trackers || [], function(_, tracker) {
tracker.remove()
});
that._trackersGroup && that._trackersGroup.detach();
that._markerTrackerGroup && that._markerTrackerGroup.detach();
that._trackers = that._trackersGroup = that._markerTrackerGroup = null
},
dispose: function() {
this._deletePoints();
this._group.detach();
this._labelsGroup && this._labelsGroup.detach();
this._deletePatterns();
this._deleteTrackers();
this._group = null;
this._markersGroup = null;
this._elementsGroup = null;
this._bordersGroup = null;
this._labelsGroup = null;
this._graphics = null;
this._rangeData = null;
this._renderer = null;
this.translators = null;
this._styles = null;
this._options = null;
this._pointOptions = null;
this._drawedPoints = null;
this._aggregatedPoints = null;
this.pointsByArgument = null;
this._segments = null
},
correctPosition: _noop,
getColor: function() {
return this.getLegendStyles().normal.fill
},
getStackName: function() {
return this.type === "stackedbar" || this.type === "fullstackedbar" ? this._stackName : null
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file rangeDataCalculator.js */
(function($, DX) {
var _math = Math,
_abs = _math.abs,
_min = _math.min,
_each = $.each,
_isEmptyObject = $.isEmptyObject,
_isDefined = DevExpress.utils.isDefined,
FULLSTACKED_SERIES_VALUE_MARGIN_PRIORITY = 15,
BAR_ZERO_VALUE_MARGIN_PRIORITY = 20,
SERIES_VALUE_MARGIN_PRIORITY = 20,
SERIES_LABEL_VALUE_MARGIN = 0.3,
CATEGORIES_SELECTOR = "categories",
INTERVAL_SELECTOR = "interval",
MIN_VALUE_MARGIN_SELECTOR = "minValueMargin",
MAX_VALUE_MARGIN_SELECTOR = "maxValueMargin",
MIN = "min",
MAX = "max",
MIN_VISIBLE = "minVisible",
MAX_VISIBLE = "maxVisible";
DevExpress.viz.core.series.helpers.rangeDataCalculator = function() {
var _truncateValue = function(data, minField, maxField, value) {
var min = data[minField],
max = data[maxField];
data[minField] = value < min || !_isDefined(min) ? value : data[minField];
data[maxField] = value > max || !_isDefined(max) ? value : data[maxField]
};
var _processTwoValues = function(series, point, prevPoint, highValueName, lowValueName) {
var val = point[highValueName],
minVal = point[lowValueName],
arg = point.argument,
prevVal = prevPoint && prevPoint[highValueName],
prevMinVal = prevPoint && prevPoint[lowValueName],
prevArg = prevPoint && prevPoint.argument;
point.hasValue() && _processRangeValue(series, val, minVal, prevVal, prevMinVal);
_processValue(series, "arg", arg, prevArg)
};
var _processValue = function(series, type, value, prevValue, calcInterval) {
var axis = type === "arg" ? "argument" : "value",
data = series._rangeData[type],
minInterval = data[INTERVAL_SELECTOR],
interval;
if (series[axis + "AxisType"] === "discrete") {
data[CATEGORIES_SELECTOR] = data[CATEGORIES_SELECTOR] || [];
data[CATEGORIES_SELECTOR].push(value)
}
else {
_truncateValue(data, "min", "max", value);
if (type === "arg") {
interval = (_isDefined(prevValue) ? _abs(calcInterval ? calcInterval(value, prevValue) : value - prevValue) : interval) || minInterval;
data[INTERVAL_SELECTOR] = _isDefined(interval) && (interval < minInterval || !_isDefined(minInterval)) ? interval : minInterval
}
}
};
var _addToVisibleRange = function(series, value) {
var data = series._rangeData.val,
isDiscrete = series.valueAxisType === "discrete";
if (isDiscrete) {
data.visibleCategories = data.visibleCategories || [];
data.visibleCategories.push(value)
}
else {
if (value < data.minVisible || !_isDefined(data.minVisible))
data.minVisible = value;
if (value > data.maxVisible || !_isDefined(data.maxVisible))
data.maxVisible = value
}
};
var _processRangeValue = function(series, val, minVal, prevVal, prevMinVal) {
var data = series._rangeData.val,
interval,
currentInterval = data[INTERVAL_SELECTOR];
if (series.valueAxisType === "discrete") {
data.categories = data.categories || [];
data.categories.push(val, minVal)
}
else {
_truncateValue(data, MIN, MAX, val);
_truncateValue(data, MIN, MAX, minVal)
}
};
var _unique = function(array) {
var values = {};
return $.map(array, function(item) {
var result = !values[item] ? item : null;
values[item] = true;
return result
})
};
var _processZoomArgument = function(series, zoomArgs) {
var data = series._rangeData.arg,
minArg,
maxArg;
minArg = zoomArgs.minArg < zoomArgs.maxArg ? zoomArgs.minArg : zoomArgs.maxArg;
maxArg = zoomArgs.maxArg > zoomArgs.minArg ? zoomArgs.maxArg : zoomArgs.minArg;
data.min = minArg < data.min ? minArg : data.min;
data.max = maxArg > data.max ? maxArg : data.max;
data.minVisible = minArg;
data.maxVisible = maxArg
};
var _correctZoomValue = function(series, zoomArgs) {
var minVal,
maxVal;
if (_isDefined(zoomArgs.minVal) && _isDefined(zoomArgs.maxVal)) {
minVal = zoomArgs.minVal < zoomArgs.maxVal ? zoomArgs.minVal : zoomArgs.maxVal;
maxVal = zoomArgs.maxVal > zoomArgs.minVal ? zoomArgs.maxVal : zoomArgs.minVal
}
if (_isDefined(zoomArgs.minVal)) {
series._rangeData.val.min = minVal < series._rangeData.val.min ? minVal : series._rangeData.val.min;
series._rangeData.val.minVisible = minVal
}
if (_isDefined(zoomArgs.maxVal)) {
series._rangeData.val.max = maxVal > series._rangeData.val.max ? maxVal : series._rangeData.val.max;
series._rangeData.val.maxVisible = maxVal
}
};
var _processZoomValue = function(series, zoomArgs) {
var adjustOnZoom = zoomArgs.adjustOnZoom,
points = series._points || [],
lastVisibleIndex,
prevPointAdded = false;
_each(points, function(index, point) {
var arg = point.argument,
prevPoint = index > 0 ? points[index - 1] : null;
if (adjustOnZoom && arg >= series._rangeData.arg.minVisible && arg <= series._rangeData.arg.maxVisible) {
if (!prevPointAdded) {
prevPoint && prevPoint.hasValue() && _addToVisibleRange(series, prevPoint.value);
prevPointAdded = true
}
point.hasValue() && _addToVisibleRange(series, point.value);
lastVisibleIndex = index
}
});
if (_isDefined(lastVisibleIndex) && lastVisibleIndex < points.length - 1 && points[lastVisibleIndex + 1].hasValue())
_addToVisibleRange(series, points[lastVisibleIndex + 1].value);
_correctZoomValue(series, zoomArgs)
};
var _processZoomRangeValue = function(series, zoomArgs, maxValueName, minValueName) {
var adjustOnZoom = zoomArgs.adjustOnZoom,
points = series._points || [],
lastVisibleIndex,
prevPointAdded = false;
_each(points, function(index, point) {
var arg = point.argument,
prevPoint = index > 0 ? points[index - 1] : null;
if (adjustOnZoom && arg >= series._rangeData.arg.minVisible && arg <= series._rangeData.arg.maxVisible) {
if (!prevPointAdded) {
if (prevPoint && prevPoint.hasValue()) {
_addToVisibleRange(series, prevPoint[maxValueName]);
_addToVisibleRange(series, prevPoint[minValueName])
}
prevPointAdded = true
}
if (point.hasValue()) {
_addToVisibleRange(series, point[maxValueName]);
_addToVisibleRange(series, point[minValueName])
}
lastVisibleIndex = index
}
});
if (_isDefined(lastVisibleIndex) && lastVisibleIndex < points.length - 1 && points[lastVisibleIndex + 1].hasValue())
_addToVisibleRange(series, points[lastVisibleIndex + 1].value);
_correctZoomValue(series, zoomArgs)
};
var _processNewInterval = function(series, calcInterval) {
var data = series._rangeData,
points = series._points || [],
isArgumentAxisDiscrete = series.argumentAxisType === "discrete";
delete data.arg.interval;
_each(points, function(index, point) {
var arg = point.argument,
prevPoint = index > 0 ? points[index - 1] : null,
prevArg = prevPoint && prevPoint.argument;
!isArgumentAxisDiscrete && _processValue(series, "arg", arg, prevArg, calcInterval)
})
};
var _fillRangeData = function(series) {
var data = series._rangeData,
mainAxis = series._getMainAxisName(),
axis = mainAxis === "X" ? "Y" : "X";
data.arg.categories && (data.arg.categories = _unique(data.arg.categories));
data.val.categories && (data.val.categories = _unique(data.val.categories));
data.arg.visibleCategories && (data.arg.visibleCategories = _unique(data.arg.visibleCategories));
data.val.visibleCategories && (data.val.visibleCategories = _unique(data.val.visibleCategories));
data.arg.axisType = series.argumentAxisType;
data.arg.dataType = series.argumentType;
data.val.axisType = series.valueAxisType;
data.val.dataType = series.valueType;
data.val.isValueRange = true
};
var _setPadding = function(range, prefix, val, priority) {
range[prefix] = val;
range[prefix + "Priority"] = priority
};
var _setZeroPadding = function(range, val, prefix) {
val === 0 && _setPadding(range, prefix, 0, BAR_ZERO_VALUE_MARGIN_PRIORITY)
};
var _calculateRangeMinValue = function(series, zoomArgs) {
var data = series._rangeData.val,
minVisible = data[MIN_VISIBLE],
maxVisible = data[MAX_VISIBLE];
zoomArgs = zoomArgs || {};
if (data) {
data.alwaysCorrectMin = true;
series._rangeData.arg.keepValueMargins = true;
if (series.valueAxisType !== "logarithmic" && series.valueType !== "datetime" && series.getOptions().showZero !== false) {
data[MIN_VISIBLE] = minVisible > (zoomArgs.minVal || 0) ? zoomArgs.minVal || 0 : minVisible;
data[MAX_VISIBLE] = maxVisible < (zoomArgs.maxVal || 0) ? zoomArgs.maxVal || 0 : maxVisible;
data[MIN] = data[MIN] > 0 ? 0 : data[MIN];
_setZeroPadding(data, data[MIN], MIN_VALUE_MARGIN_SELECTOR);
data[MAX] = data[MAX] < 0 ? 0 : data[MAX];
if (data[MAX] === 0 || data[MAX] > 0 && data[MIN] < 0) {
data[MIN_VALUE_MARGIN_SELECTOR] = data[MAX_VALUE_MARGIN_SELECTOR];
data[MIN_VALUE_MARGIN_SELECTOR + "Priority"] = data[MAX_VALUE_MARGIN_SELECTOR + "Priority"]
}
_setZeroPadding(data, data[MAX], MAX_VALUE_MARGIN_SELECTOR)
}
}
};
var _processFullStackedRange = function(series) {
var data = series._rangeData.val,
isRangeEmpty = _isEmptyObject(data);
_setPadding(data, "minValueMargin", 0, FULLSTACKED_SERIES_VALUE_MARGIN_PRIORITY);
_setPadding(data, "maxValueMargin", 0, FULLSTACKED_SERIES_VALUE_MARGIN_PRIORITY);
!isRangeEmpty && (data.min = 0)
};
var _processRange = function(series, point, prevPoint) {
var val = point.value,
arg = point.argument,
prevVal = prevPoint && prevPoint.value,
prevArg = prevPoint && prevPoint.argument;
point.hasValue() && _processValue(series, "val", val, prevVal);
_processValue(series, "arg", arg, prevArg)
};
var _addLabelPaddings = function(series) {
var labelOptions = series.getOptions().label;
if (series.areLabelsVisible() && labelOptions && labelOptions.visible && labelOptions.position !== "inside")
_setPadding(series._rangeData.val, "maxValueMargin", SERIES_LABEL_VALUE_MARGIN, SERIES_VALUE_MARGIN_PRIORITY)
};
var _addRangeSeriesLabelPaddings = function(series) {
var data = series._rangeData.val;
if (series.areLabelsVisible() && series._options.label.visible && series._options.label.position !== "inside") {
_setPadding(data, "maxValueMargin", SERIES_LABEL_VALUE_MARGIN, SERIES_VALUE_MARGIN_PRIORITY);
_setPadding(data, "minValueMargin", SERIES_LABEL_VALUE_MARGIN, SERIES_VALUE_MARGIN_PRIORITY)
}
};
var _calculateRangeData = function(series, zoomArgs, calcIntervalFunction) {
var valueData = series._rangeData.val;
if (series.argumentAxisType !== "discrete" && zoomArgs && _isDefined(zoomArgs.minArg) && _isDefined(zoomArgs.maxArg)) {
valueData[MIN_VISIBLE] = zoomArgs.minVal;
valueData[MAX_VISIBLE] = zoomArgs.maxVal;
_processZoomArgument(series, zoomArgs);
_processZoomValue(series, zoomArgs)
}
else if (!zoomArgs && calcIntervalFunction)
_processNewInterval(series, calcIntervalFunction);
_fillRangeData(series)
};
var _calculateTwoValuesRangeData = function(series, zoomArgs, calcIntervalFunction, maxValueName, minValueName) {
var valueData = series._rangeData.val;
if (series.argumentAxisType !== "discrete" && zoomArgs && _isDefined(zoomArgs.minArg) && _isDefined(zoomArgs.maxArg)) {
valueData[MIN_VISIBLE] = zoomArgs.minVal;
valueData[MAX_VISIBLE] = zoomArgs.maxVal;
_processZoomArgument(series, zoomArgs);
_processZoomRangeValue(series, zoomArgs, maxValueName, minValueName)
}
else if (!zoomArgs && calcIntervalFunction)
_processNewInterval(series);
_fillRangeData(series)
};
return {
processRange: _processRange,
calculateRangeData: _calculateRangeData,
calculateTwoValuesRangeData: _calculateTwoValuesRangeData,
addLabelPaddings: _addLabelPaddings,
addRangeSeriesLabelPaddings: _addRangeSeriesLabelPaddings,
processFullStackedRange: _processFullStackedRange,
calculateRangeMinValue: _calculateRangeMinValue,
processTwoValues: _processTwoValues
}
}
})(jQuery, DevExpress);
/*! Module viz-core, file scatterSeries.js */
(function($, DX) {
var viz = DX.viz,
series = viz.core.series,
rangeCalculator = series.helpers.rangeDataCalculator(),
_each = $.each,
_extend = $.extend,
_map = $.map,
_noop = $.noop,
_isDefined = DX.utils.isDefined,
_floor = Math.floor,
DEFAULT_SYMBOL_POINT_SIZE = 2,
DEFAULT_TRACKER_WIDTH = 20,
DEFAULT_DURATION = 400;
series.mixins.chart.scatter = {
_defaultDuration: DEFAULT_DURATION,
_defaultTrackerWidth: DEFAULT_TRACKER_WIDTH,
_applyStyle: _noop,
_adjustLabels: _noop,
_updateOptions: _noop,
_parseStyle: _noop,
_prepareSegment: _noop,
_drawSegment: _noop,
_generateDefaultSegments: _noop,
_prepareSeriesToDrawing: function() {
this._deleteOldAnimationMethods();
this._firstDrawing && this._clearSeries();
this._disposePoints(this._oldPoints);
this._oldPoints = null
},
_applyTrackersClippings: function() {
this._markerTrackerGroup.applySettings({clipId: this._forceClipping ? this._paneClipRectID : null})
},
updateTeamplateFieldNames: function() {
var that = this,
options = that._options;
options.valueField = that.getValueFields()[0] + that.name;
options.tagField = that.getTagField() + that.name
},
_applyElementsClipRect: function(settings) {
settings.clipId = this._paneClipRectID
},
_applyMarkerClipRect: function(settings) {
settings.clipId = this._forceClipping ? this._paneClipRectID : null
},
_createGroup: function(groupName, parent, target, settings) {
var group = parent[groupName];
if (!group)
parent[groupName] = group = this._renderer.createGroup(settings);
else
group.applySettings(settings);
group.append(target)
},
_applyClearingSettings: function(settings) {
settings.opacity = null;
settings.scale = null;
if (this._options.rotated)
settings.translateX = null;
else
settings.translateY = null
},
_createMarkerGroup: function() {
var settings = this._getPointOptions().styles.normal;
settings["class"] = "dxc-markers";
settings.opacity = 1;
this._applyMarkerClipRect(settings);
this._createGroup("_markersGroup", this, this._group, settings)
},
_createLabelGroup: function() {
var settings = {
"class": "dxc-labels",
visibility: this.getLabelVisibility() ? "visible" : "hidden"
};
this._applyElementsClipRect(settings);
this._applyClearingSettings(settings);
this._createGroup("_labelsGroup", this, this._options.labelsGroup, settings)
},
_createGroups: function(animationEnabled) {
this._createMarkerGroup();
this._createLabelGroup();
animationEnabled && this._labelsGroup && this._labelsGroup.applySettings({opacity: 0.001})
},
_getCreatingPointOptions: function() {
if (!this._predefinedPointOptions) {
var defaultPointOptions = this._getPointOptions(),
r = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.r,
strokeWidth = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.strokeWidth,
creatingPointOptions = _extend(true, {}, defaultPointOptions);
creatingPointOptions.styles = creatingPointOptions.styles || {};
creatingPointOptions.styles.normal = {
r: r,
strokeWidth: strokeWidth
};
this._predefinedPointOptions = creatingPointOptions
}
return this._predefinedPointOptions
},
_getSpecialColor: function(mainSeriesColor) {
return mainSeriesColor
},
_getPointOptions: function() {
return this._pointOptions || (this._pointOptions = this._parsePointOptions(this._preparePointOptions(), this._options.label))
},
_preparePointOptions: function(customOptions) {
return customOptions ? _extend(true, {}, this._options.point, customOptions) : this._options.point
},
_parsePointStyle: function(style, defaultColor, defaultBorderColor) {
var border = style.border || {};
return {
fill: style.color || defaultColor,
stroke: border.color || defaultBorderColor,
strokeWidth: border.visible ? border.width : 0,
r: style.size / 2 + (border.visible && style.size !== 0 ? ~~(border.width / 2) || 0 : 0)
}
},
_createPointStyles: function(pointOptions) {
var mainPointColor = pointOptions.color || this._options.mainSeriesColor,
containerColor = this._options.containerBackgroundColor,
normalStyle = this._parsePointStyle(pointOptions, mainPointColor, mainPointColor);
normalStyle.visibility = pointOptions.visible ? "visible" : "hidden";
return {
normal: normalStyle,
hover: this._parsePointStyle(pointOptions.hoverStyle, containerColor, mainPointColor),
selection: this._parsePointStyle(pointOptions.selectionStyle, containerColor, mainPointColor)
}
},
_checkData: function(data) {
return _isDefined(data.argument) && data.value !== undefined
},
_processRange: function(point, prevPoint) {
rangeCalculator.processRange(this, point, prevPoint)
},
_getRangeData: function(zoomArgs, calcIntervalFunction) {
rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
rangeCalculator.addLabelPaddings(this);
return this._rangeData
},
_getPointData: function(data, options) {
var argumentField = options.argumentField || "arg",
valueField = options.valueField || "val",
tagField = options.tagField || "tag";
return {
value: data[valueField],
argument: data[argumentField],
tag: data[tagField]
}
},
_drawPoint: function(point, markersGroup, labelsGroup, animationEnabled, firstDrawing) {
if (point.isInVisibleArea()) {
point.clearVisibility();
point.draw(this._renderer, markersGroup, labelsGroup, animationEnabled, firstDrawing);
this._drawedPoints.push(point)
}
else
point.setInvisibility()
},
_clearingAnimation: function(translators, drawComplete) {
var that = this,
params = {opacity: 0.001},
options = {
duration: that._defaultDuration,
partitionDuration: 0.5
};
that._labelsGroup && that._labelsGroup.animate(params, options, function() {
that._markersGroup && that._markersGroup.animate(params, options, drawComplete)
})
},
_animate: function(complete) {
var that = this,
lastPointIndex = that._drawedPoints.length - 1,
labelAnimFunc = function() {
that._labelsGroup && that._labelsGroup.animate({opacity: 1}, {duration: that._defaultDuration})
},
settings;
_each(that._drawedPoints || [], function(i, p) {
settings = {translate: {
x: p.x,
y: p.y
}};
p.animate(i === lastPointIndex ? labelAnimFunc : undefined, settings)
})
},
_getPointSize: function() {
return this._options.point.visible ? this._options.point.size : DEFAULT_SYMBOL_POINT_SIZE
},
_calcMedianValue: function(fusionPoints, valueField) {
var result,
allValue;
allValue = _map(fusionPoints, function(point) {
return point[valueField]
});
allValue.sort(function(a, b) {
return a - b
});
result = allValue[_floor(allValue.length / 2)];
return _isDefined(result) ? result : null
},
_fusionPoints: function(fusionPoints, tick, index) {
var result = this._calcMedianValue(fusionPoints, "value");
return {
value: result,
argument: tick,
tag: null,
index: index,
seriesName: this.name
}
},
_endUpdateData: function() {
delete this._predefinedPointOptions
},
getArgumentField: function() {
return this._options.argumentField || "arg"
},
getValueFields: function() {
return [this._options.valueField || "val"]
},
_beginUpdateData: $.noop
}
})(jQuery, DevExpress);
/*! Module viz-core, file lineSeries.js */
(function($, DX) {
var viz = DX.viz,
series = viz.core.series.mixins.chart,
utils = DX.utils,
scatterSeries = series.scatter,
_extend = $.extend,
_map = $.map,
_each = $.each;
series.line = _extend({}, scatterSeries, {
_createElementsGroup: function(elementsStyle) {
var settings = _extend({"class": "dxc-elements"}, elementsStyle);
this._applyElementsClipRect(settings);
this._createGroup("_elementsGroup", this, this._group, settings)
},
_createBordersGroup: function(borderStyle) {
var settings = _extend({"class": "dxc-borders"}, borderStyle);
this._applyElementsClipRect(settings);
this._createGroup("_bordersGroup", this, this._group, settings)
},
_applyTrackersClippings: function() {
scatterSeries._applyTrackersClippings.call(this);
this._trackersGroup.applySettings({clipId: this._paneClipRectID})
},
_createGroups: function(animationEnabled, style) {
var style = style || this._styles.normal;
this._createElementsGroup(style.elements);
this._areBordersVisible() && this._createBordersGroup(style.border);
scatterSeries._createGroups.call(this, animationEnabled, {});
animationEnabled && this._markersGroup && this._markersGroup.applySettings({opacity: 0.001})
},
_areBordersVisible: function() {
return false
},
_getDefaultSegment: function(segment) {
return {line: _map(segment.line || [], function(pt) {
return pt.getDefaultCoords()
})}
},
_prepareSegment: function(points) {
return {line: points}
},
_parseLineOptions: function(options, defaultColor) {
return {
stroke: options.color || defaultColor,
strokeWidth: options.width,
dashStyle: options.dashStyle || 'solid'
}
},
_parseStyle: function(options, defaultColor) {
return {elements: this._parseLineOptions(options, defaultColor)}
},
_applyStyle: function(style) {
this._elementsGroup && this._elementsGroup.applySettings(style.elements);
_each(this._graphics || [], function(_, graphic) {
graphic.line && graphic.line.applySettings({strokeWidth: style.elements.strokeWidth})
})
},
_drawElement: function(segment, group) {
return {line: this._createMainElement(segment.line, {strokeWidth: this._styles.normal.elements.strokeWidth}).append(group)}
},
_removeElement: function(element) {
element.line.remove()
},
_generateDefaultSegments: function() {
var that = this,
segments = [];
_each(that._segments || [], function(_, segment) {
segments.push(that._getDefaultSegment(segment))
});
return segments
},
_updateElement: function(element, segment, animate, animateParams, complete) {
var params = {points: segment.line};
animate ? element.line.animate(params, animateParams, complete) : element.line.applySettings(params)
},
_clearingAnimation: function(translator, drawComplete) {
var that = this,
lastIndex = that._graphics.length - 1,
settings = {opacity: 0.001},
options = {
duration: that._defaultDuration,
partitionDuration: 0.5
};
that._labelsGroup && that._labelsGroup.animate(settings, options, function() {
that._markersGroup && that._markersGroup.animate(settings, options, function() {
_each(that._defaultSegments || [], function(i, segment) {
that._oldUpdateElement(that._graphics[i], segment, true, {partitionDuration: 0.5}, i === lastIndex ? drawComplete : undefined)
})
})
})
},
_animate: function() {
var that = this,
lastIndex = that._graphics.length - 1;
_each(that._graphics || [], function(i, elem) {
that._updateElement(elem, that._segments[i], true, {complete: i === lastIndex ? function() {
that._labelsGroup && that._labelsGroup.animate({opacity: 1}, {duration: that._defaultDuration});
that._markersGroup && that._markersGroup.animate({opacity: 1}, {duration: that._defaultDuration})
} : undefined})
})
},
_drawPoint: function(point, group, labelsGroup) {
scatterSeries._drawPoint.call(this, point, group, labelsGroup)
},
_createMainElement: function(points, settings) {
return this._renderer.createPath(points, settings)
},
_drawSegment: function(points, animationEnabled, segmentCount) {
var segment = this._prepareSegment(points, this._options.rotated);
this._segments.push(segment);
if (!this._graphics[segmentCount])
this._graphics[segmentCount] = this._drawElement(animationEnabled ? this._getDefaultSegment(segment) : segment, this._elementsGroup);
else if (!animationEnabled)
this._updateElement(this._graphics[segmentCount], segment)
},
_getTrackerSettings: function() {
return {
strokeWidth: this._styles.normal.elements.strokeWidth > this._defaultTrackerWidth ? this._styles.normal.elements.strokeWidth : this._defaultTrackerWidth,
fill: "none"
}
},
_getMainPointsFromSegment: function(segment) {
return segment.line
},
_drawTrackerElement: function(segment) {
return this._createMainElement(this._getMainPointsFromSegment(segment), this._getTrackerSettings(segment))
},
_updateTrackerElement: function(segment, element) {
var settings = this._getTrackerSettings(segment);
settings.points = this._getMainPointsFromSegment(segment);
element.applySettings(settings)
}
});
series.stepline = _extend({}, series.line, {
_calculateStepLinePoints: function(points) {
var segment = [];
_each(points, function(i, pt) {
var stepY;
if (!i) {
segment.push(pt);
return
}
stepY = segment[segment.length - 1].y;
if (stepY !== pt.y) {
var point = utils.clone(pt);
point.y = stepY;
segment.push(point)
}
segment.push(pt)
});
return segment
},
_prepareSegment: function(points) {
return series.line._prepareSegment(this._calculateStepLinePoints(points))
}
});
series.stackedline = _extend({}, series.line, {});
series.fullstackedline = _extend({}, series.line, {_getRangeData: function(zoomArgs, calcIntervalFunction) {
var rangeCalculator = viz.core.series.helpers.rangeDataCalculator();
rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
rangeCalculator.addLabelPaddings(this);
rangeCalculator.processFullStackedRange(this);
return this._rangeData
}});
series.spline = _extend({}, series.line, {
_calculateBezierPoints: function(src, rotated) {
var bezierPoints = [],
pointsCopy = src;
var checkExtr = function(otherPointCoord, pointCoord, controlCoord) {
return otherPointCoord > pointCoord && controlCoord > otherPointCoord || otherPointCoord < pointCoord && controlCoord < otherPointCoord ? otherPointCoord : controlCoord
};
var clonePoint = function(point, newX, newY) {
var p = utils.clone(point);
p.x = newX;
p.y = newY;
return p
};
if (pointsCopy.length !== 1)
_each(pointsCopy, function(i, curPoint) {
var leftControlX,
leftControlY,
rightControlX,
rightControlY,
prevPoint,
nextPoint,
xCur,
yCur,
x1,
x2,
y1,
y2,
delta,
lambda = 0.5,
curIsExtremum,
leftPoint,
rightPoint,
a,
b,
c,
xc,
yc,
shift;
if (!i) {
bezierPoints.push(curPoint);
bezierPoints.push(curPoint);
return
}
prevPoint = pointsCopy[i - 1];
if (i < pointsCopy.length - 1) {
nextPoint = pointsCopy[i + 1];
xCur = curPoint.x;
yCur = curPoint.y;
x1 = prevPoint.x;
x2 = nextPoint.x;
y1 = prevPoint.y;
y2 = nextPoint.y;
curIsExtremum = !!(!rotated && (yCur <= prevPoint.y && yCur <= nextPoint.y || yCur >= prevPoint.y && yCur >= nextPoint.y) || rotated && (xCur <= prevPoint.x && xCur <= nextPoint.x || xCur >= prevPoint.x && xCur >= nextPoint.x));
if (curIsExtremum)
if (!rotated) {
rightControlY = leftControlY = yCur;
rightControlX = (xCur + nextPoint.x) / 2;
leftControlX = (xCur + prevPoint.x) / 2
}
else {
rightControlX = leftControlX = xCur;
rightControlY = (yCur + nextPoint.y) / 2;
leftControlY = (yCur + prevPoint.y) / 2
}
else {
a = y2 - y1;
b = x1 - x2;
c = y1 * x2 - x1 * y2;
if (!rotated) {
xc = xCur;
yc = -1 * (a * xc + c) / b;
shift = yc - yCur || 0;
y1 -= shift;
y2 -= shift
}
else {
yc = yCur;
xc = -1 * (b * yc + c) / a;
shift = xc - xCur || 0;
x1 -= shift;
x2 -= shift
}
rightControlX = (xCur + lambda * x2) / (1 + lambda);
rightControlY = (yCur + lambda * y2) / (1 + lambda);
leftControlX = (xCur + lambda * x1) / (1 + lambda);
leftControlY = (yCur + lambda * y1) / (1 + lambda)
}
if (!rotated) {
leftControlY = checkExtr(prevPoint.y, yCur, leftControlY);
rightControlY = checkExtr(nextPoint.y, yCur, rightControlY)
}
else {
leftControlX = checkExtr(prevPoint.x, xCur, leftControlX);
rightControlX = checkExtr(nextPoint.x, xCur, rightControlX)
}
leftPoint = clonePoint(curPoint, leftControlX, leftControlY);
rightPoint = clonePoint(curPoint, rightControlX, rightControlY);
bezierPoints.push(leftPoint, curPoint, rightPoint)
}
else {
bezierPoints.push(curPoint, curPoint);
return
}
});
else
bezierPoints.push(pointsCopy[0]);
return bezierPoints
},
_prepareSegment: function(points, rotated) {
return series.line._prepareSegment(this._calculateBezierPoints(points, rotated))
},
_createMainElement: function(points, settings) {
return this._renderer.createBezierPath(points, settings)
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file areaSeries.js */
(function($, DX) {
var viz = DX.viz,
utils = DX.utils,
series = viz.core.series.mixins.chart,
lineSeries = series.line,
_map = $.map,
_extend = $.extend,
HOVER_COLOR_HIGHLIGHTING = 20;
series.area = _extend({}, lineSeries, {
_createBorderElement: lineSeries._createMainElement,
_processSinglePointsAreaSegment: function(points, rotated) {
if (points.length == 1) {
var p = points[0],
p1 = utils.clone(p),
coord = rotated ? "y" : "x";
p1[coord] += 1;
return [p, p1]
}
return points
},
_prepareSegment: function(points, rotated) {
var processedPoints = this._processSinglePointsAreaSegment(points, rotated);
return {
line: processedPoints,
area: _map(processedPoints, function(pt) {
return pt.getCoords()
}).concat(_map(processedPoints.slice().reverse(), function(pt) {
return pt.getCoords(true)
})),
singlePointSegment: processedPoints !== points
}
},
_getSpecialColor: function(color) {
return this._options._IE8 ? new DX.Color(color).highlight(HOVER_COLOR_HIGHLIGHTING) : color
},
_getRangeData: function(zoomArgs, calcIntervalFunction) {
var rangeCalculator = viz.core.series.helpers.rangeDataCalculator();
rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
rangeCalculator.addLabelPaddings(this);
rangeCalculator.calculateRangeMinValue(this, zoomArgs);
return this._rangeData
},
_getDefaultSegment: function(segment) {
var defaultSegment = lineSeries._getDefaultSegment(segment);
defaultSegment.area = defaultSegment.line.concat(defaultSegment.line.slice().reverse());
return defaultSegment
},
_updateElement: function(element, segment, animate, animateParams, complete) {
var lineParams = {points: segment.line},
areaParams = {points: segment.area},
borderElement = element.line;
if (animate) {
borderElement && borderElement.animate(lineParams, animateParams);
element.area.animate(areaParams, animateParams, complete)
}
else {
borderElement && borderElement.applySettings(lineParams);
element.area.applySettings(areaParams)
}
},
_removeElement: function(element) {
element.line && element.line.remove();
element.area.remove()
},
_drawElement: function(segment, group) {
return {
line: this._bordersGroup && this._createBorderElement(segment.line, {strokeWidth: this._styles.normal.border.strokeWidth}).append(this._bordersGroup),
area: this._createMainElement(segment.area).append(this._elementsGroup)
}
},
_applyStyle: function(style) {
this._elementsGroup && this._elementsGroup.applySettings(style.elements);
this._bordersGroup && this._bordersGroup.applySettings(style.border);
$.each(this._graphics || [], function(_, graphic) {
graphic.line && graphic.line.applySettings({strokeWidth: style.border.strokeWidth})
})
},
_createPattern: function(color, hatching) {
if (hatching && utils.isObject(hatching)) {
var pattern = this._renderer.createPattern(color, hatching);
this._patterns.push(pattern);
return pattern.id
}
return color
},
_parseStyle: function(options, defaultColor, defaultBorderColor) {
var borderOptions = options.border || {},
borderStyle = lineSeries._parseLineOptions(borderOptions, defaultBorderColor);
borderStyle.strokeWidth = borderOptions.visible ? borderStyle.strokeWidth : 0;
return {
border: borderStyle,
elements: {
stroke: "none",
fill: this._createPattern(options.color || defaultColor, options.hatching),
opacity: options.opacity
}
}
},
_areBordersVisible: function() {
var options = this._options;
return options.border.visible || options.hoverStyle.border.visible || options.selectionStyle.border.visible
},
_createMainElement: function(points, settings) {
return this._renderer.createArea(points, settings)
},
_getTrackerSettings: function(segment) {
return {strokeWidth: segment.singlePointSegment ? this._defaultTrackerWidth : 0}
},
_getMainPointsFromSegment: function(segment) {
return segment.area
}
});
series.steparea = _extend({}, series.area, {_prepareSegment: function(points, rotated) {
points = series.area._processSinglePointsAreaSegment(points, rotated);
return series.area._prepareSegment.call(this, series.stepline._calculateStepLinePoints(points))
}});
series.splinearea = _extend({}, series.area, {
_areaPointsToSplineAreaPoints: function(areaPoints) {
var lastFwPoint = areaPoints[areaPoints.length / 2 - 1],
firstBwPoint = areaPoints[areaPoints.length / 2];
areaPoints.splice(areaPoints.length / 2, 0, {
x: lastFwPoint.x,
y: lastFwPoint.y
}, {
x: firstBwPoint.x,
y: firstBwPoint.y
});
if (lastFwPoint.defaultCoords)
areaPoints[areaPoints.length / 2].defaultCoords = true;
if (firstBwPoint.defaultCoords)
areaPoints[areaPoints.length / 2 - 1].defaultCoords = true
},
_prepareSegment: function(points, rotated) {
var areaSeries = series.area,
processedPoints = areaSeries._processSinglePointsAreaSegment(points, rotated),
areaSegment = areaSeries._prepareSegment.call(this, series.spline._calculateBezierPoints(processedPoints, rotated));
this._areaPointsToSplineAreaPoints(areaSegment.area);
areaSegment.singlePointSegment = processedPoints !== points;
return areaSegment
},
_getDefaultSegment: function(segment) {
var areaDefaultSegment = series.area._getDefaultSegment(segment);
this._areaPointsToSplineAreaPoints(areaDefaultSegment.area);
return areaDefaultSegment
},
_createMainElement: function(points, settings) {
return this._renderer.createBezierArea(points, settings)
},
_createBorderElement: series.spline._createMainElement
})
})(jQuery, DevExpress);
/*! Module viz-core, file barSeries.js */
(function($, DX) {
var viz = DX.viz,
series = viz.core.series.mixins.chart,
scatterSeries = series.scatter,
areaSeries = series.area,
_extend = $.extend,
_each = $.each,
DEFAULT_BAR_POINT_SIZE = 3;
series.bar = _extend({}, scatterSeries, {
_getSpecialColor: areaSeries._getSpecialColor,
_createPattern: areaSeries._createPattern,
_updateOptions: function(options) {
this._stackName = "axis_" + (options.axis || "default") + "_stack_" + (options.stack || "default")
},
_getRangeData: function(zoomArgs, calcIntervalFunction) {
var rangeData = areaSeries._getRangeData.apply(this, arguments);
rangeData.arg.stick = false;
return rangeData
},
_parsePointStyle: function(style, defaultColor, defaultBorderColor) {
var color = this._createPattern(style.color || defaultColor, style.hatching),
base = scatterSeries._parsePointStyle.call(this, style, color, defaultBorderColor);
base.fill = color;
base.dashStyle = style.border && style.border.dashStyle || "solid";
delete base.r;
return base
},
_applyMarkerClipRect: function(settings) {
settings.clipId = null
},
_applyTrackersClippings: function() {
this._markerTrackerGroup.applySettings({clipId: this._paneClipRectID})
},
_clearingAnimation: function(translators, drawComplete) {
var that = this,
settings;
if (that._options.rotated)
settings = {
scale: {
x: 0.001,
y: 1
},
translate: {x: translators.x.translate("canvas_position_default")}
};
else
settings = {
scale: {
x: 1,
y: 0.001
},
translate: {y: translators.y.translate("canvas_position_default")}
};
that._labelsGroup && that._labelsGroup.animate({opacity: 0.001}, {
duration: that._defaultDuration,
partitionDuration: 0.5
}, function() {
that._markersGroup.animate(settings, {partitionDuration: 0.5}, function() {
that._markersGroup.applySettings({
scale: null,
translateX: 0,
translateY: 0
});
drawComplete()
})
})
},
_createGroups: function(animationEnabled, style, firstDrawing) {
var settings = {};
scatterSeries._createGroups.apply(this, arguments);
if (animationEnabled && firstDrawing)
if (!this._options.rotated)
settings = {
scale: {
x: 1,
y: 0.001
},
translateY: this.translators.y.translate("canvas_position_default")
};
else
settings = {
scale: {
x: 0.001,
y: 1
},
translateX: this.translators.x.translate("canvas_position_default")
};
else if (!animationEnabled)
settings = {
scale: {
x: 1,
y: 1
},
translateX: 0,
translateY: 0
};
this._markersGroup.applySettings(settings)
},
_drawPoint: function(point, markersGroup, labelsGroup, animationEnabled, firstDrawing) {
scatterSeries._drawPoint.call(this, point, markersGroup, labelsGroup, animationEnabled && !firstDrawing)
},
_getMainColor: function() {
return this._options.mainSeriesColor
},
_createPointStyles: function(pointOptions) {
var mainColor = pointOptions.color || this._getMainColor(),
specialMainColor = this._getSpecialColor(mainColor);
return {
normal: this._parsePointStyle(pointOptions, mainColor, mainColor),
hover: this._parsePointStyle(pointOptions.hoverStyle || {}, specialMainColor, mainColor),
selection: this._parsePointStyle(pointOptions.selectionStyle || {}, specialMainColor, mainColor)
}
},
_preparePointOptions: function(customOptions) {
return customOptions ? _extend(true, {}, this._options, customOptions) : this._options
},
_animate: function(firstDrawing) {
var that = this,
labelAnimFunc = function() {
that._labelsGroup && that._labelsGroup.animate({opacity: 1}, {duration: that._defaultDuration})
},
lastPointIndex;
that._markersGroup.animate({
scale: {
x: 1,
y: 1
},
translate: {
y: 0,
x: 0
}
}, undefined, labelAnimFunc);
if (!firstDrawing) {
lastPointIndex = that._drawedPoints.length - 1;
_each(this._drawedPoints || [], function(i, point) {
point.animate(i === lastPointIndex ? labelAnimFunc : undefined, {
x: point.x,
y: point.y,
height: point.height,
width: point.width
})
})
}
},
_getPointSize: function() {
return DEFAULT_BAR_POINT_SIZE
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file rangeSeries.js */
(function($, DX) {
var viz = DX.viz,
series = viz.core.series.mixins.chart,
_extend = $.extend,
_isDefined = DX.utils.isDefined,
_map = $.map,
rangeCalculator = viz.core.series.helpers.rangeDataCalculator(),
areaSeries = series.area;
var baseRangeSeries = {
_checkData: function(data) {
return _isDefined(data.argument) && data.value !== undefined && data.minValue !== undefined
},
updateTeamplateFieldNames: function() {
var that = this,
options = that._options,
valueFields = that.getValueFields(),
name = that.name;
options.rangeValue1Field = valueFields[0] + name;
options.rangeValue2Field = valueFields[1] + name;
options.tagField = that.getTagField() + name
},
_processRange: function(point, prevPoint) {
rangeCalculator.processTwoValues(this, point, prevPoint, "value", "minValue")
},
_getRangeData: function(zoomArgs, calcIntervalFunction) {
rangeCalculator.calculateTwoValuesRangeData(this, zoomArgs, calcIntervalFunction, "value", "minValue");
rangeCalculator.addRangeSeriesLabelPaddings(this);
return this._rangeData
},
_getPointData: function(data, options) {
var argumentField = options.argumentField || "arg",
tagField = options.tagField || "tag",
rangeValue1Field = options.rangeValue1Field || "val1",
rangeValue2Field = options.rangeValue2Field || "val2";
return {
tag: data[tagField],
minValue: data[rangeValue1Field],
value: data[rangeValue2Field],
argument: data[argumentField]
}
},
_fusionPoints: function(fusionPoints, tick, index) {
var scatterSeries = series.scatter,
value = scatterSeries._calcMedianValue.call(this, fusionPoints, "value"),
minValue = scatterSeries._calcMedianValue.call(this, fusionPoints, "minValue"),
pointData;
if (value === null || minValue === null)
value = minValue = null;
pointData = {
minValue: minValue,
value: value,
argument: tick,
tag: null
};
return pointData
},
getValueFields: function() {
return [this._options.rangeValue1Field || "val1", this._options.rangeValue2Field || "val2"]
}
};
series.rangebar = _extend({}, series.bar, baseRangeSeries);
series.rangearea = _extend({}, areaSeries, {
_drawPoint: function(point, markersGroup, labelsGroup, animationEnabled) {
if (point.isInVisibleArea()) {
point.clearVisibility();
point.draw(this._renderer, markersGroup, labelsGroup, animationEnabled);
this._drawedPoints.push(point);
if (!point.visibleTopMarker)
point.hideMarker("top");
if (!point.visibleBottomMarker)
point.hideMarker("bottom")
}
else
point.setInvisibility()
},
_prepareSegment: function(points, rotated) {
var processedPoints = this._processSinglePointsAreaSegment(points, rotated),
processedMinPointsCoords = $.map(processedPoints, function(pt) {
return pt.getCoords(true)
});
return {
line: processedPoints,
bottomLine: processedMinPointsCoords,
area: $.map(processedPoints, function(pt) {
return pt.getCoords()
}).concat(processedMinPointsCoords.slice().reverse()),
singlePointSegment: processedPoints !== points
}
},
_getDefaultSegment: function(segment) {
var defaultSegment = areaSeries._getDefaultSegment.call(this, segment);
defaultSegment.bottomLine = defaultSegment.line;
return defaultSegment
},
_removeElement: function(element) {
areaSeries._removeElement.call(this, element);
element.bottomLine && element.bottomLine.remove()
},
_drawElement: function(segment, group) {
var drawnElement = areaSeries._drawElement.call(this, segment, group);
drawnElement.bottomLine = this._bordersGroup && this._createBorderElement(segment.bottomLine, {strokeWidth: this._styles.normal.border.strokeWidth}).append(this._bordersGroup);
return drawnElement
},
_applyStyle: function(style) {
this._elementsGroup && this._elementsGroup.applySettings(style.elements);
this._bordersGroup && this._bordersGroup.applySettings(style.border);
$.each(this._graphics || [], function(_, graphic) {
graphic.line && graphic.line.applySettings({strokeWidth: style.border.strokeWidth});
graphic.bottomLine && graphic.bottomLine.applySettings({strokeWidth: style.border.strokeWidth})
})
},
_updateElement: function(element, segment, animate, animateParams, complete) {
areaSeries._updateElement.call(this, element, segment, animate, animateParams, complete);
var bottomLineParams = {points: segment.bottomLine},
bottomBorderElement = element.bottomLine;
if (bottomBorderElement)
animate ? bottomBorderElement.animate(bottomLineParams, animateParams) : bottomBorderElement.applySettings(bottomLineParams)
}
}, baseRangeSeries)
})(jQuery, DevExpress);
/*! Module viz-core, file bubbleSeries.js */
(function($, DX) {
var viz = DX.viz,
series = viz.core.series.mixins.chart,
scatterSeries = series.scatter,
barSeries = series.bar,
_isDefined = DX.utils.isDefined,
_extend = $.extend,
_each = $.each;
series.bubble = _extend({}, scatterSeries, {
_applyTrackersClippings: barSeries._applyTrackersClippings,
_getMainColor: barSeries._getMainColor,
_createPointStyles: barSeries._createPointStyles,
_createPattern: barSeries._createPattern,
_preparePointOptions: barSeries._preparePointOptions,
_getSpecialColor: barSeries._getSpecialColor,
_applyMarkerClipRect: series.line._applyElementsClipRect,
_parsePointStyle: function(style, defaultColor, defaultBorderColor) {
var base = barSeries._parsePointStyle.call(this, style, defaultColor, defaultBorderColor);
base.opacity = style.opacity;
return base
},
_createMarkerGroup: function() {
var markersSettings = this._getPointOptions().styles.normal,
groupSettings;
markersSettings["class"] = "dxc-markers";
this._applyMarkerClipRect(markersSettings);
groupSettings = _extend({}, markersSettings);
delete groupSettings.opacity;
this._createGroup("_markersGroup", this, this._group, groupSettings)
},
_getCreatingPointOptions: function() {
if (!this._predefinedPointOptions) {
var styles,
defaultPointOptions = this._getPointOptions(),
strokeWidth = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.strokeWidth,
r = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.r,
opacity = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.opacity,
creatingPointOptions = _extend(true, {}, defaultPointOptions);
creatingPointOptions.styles = styles = creatingPointOptions.styles || {};
styles.normal = {
strokeWidth: strokeWidth,
r: r,
opacity: opacity
};
this._predefinedPointOptions = creatingPointOptions
}
return this._predefinedPointOptions
},
_checkData: function(data) {
return _isDefined(data.argument) && _isDefined(data.size) && data.value !== undefined
},
_getPointData: function(data, options) {
var pointData = scatterSeries._getPointData.call(this, data, options),
sizeField = options.sizeField || "size";
pointData.size = data[sizeField];
return pointData
},
_fusionPoints: function(fusionPoints, tick, index) {
var medianValue = scatterSeries._calcMedianValue.call(this, fusionPoints, "value"),
medianSize = scatterSeries._calcMedianValue.call(this, fusionPoints, "size");
return {
size: medianSize,
value: medianValue,
argument: tick,
tag: null
}
},
getValueFields: function() {
return [this._options.valueField || "val", this._options.sizeField || "size"]
},
updateTeamplateFieldNames: function() {
var that = this,
options = that._options,
valueFields = that.getValueFields(),
name = that.name;
options.valueField = valueFields[0] + name;
options.sizeField = valueFields[1] + name;
options.tagField = that.getTagField() + name
},
_clearingAnimation: function(translators, drawComplete) {
var that = this,
settings = {r: 0},
partitionDuration = 0.5,
lastPointIndex = that._drawedPoints.length - 1;
that._labelsGroup && that._labelsGroup.animate({opacity: 0.001}, {
duration: that._defaultDuration,
partitionDuration: partitionDuration
}, function() {
_each(that._drawedPoints || [], function(i, p) {
p.animate(i === lastPointIndex ? drawComplete : undefined, settings, partitionDuration)
})
})
},
_animate: function(firstDrawing) {
var that = this,
lastPointIndex = that._drawedPoints.length - 1,
labelAnimFunc = function() {
that._labelsGroup && that._labelsGroup.animate({opacity: 1}, {duration: that._defaultDuration})
};
_each(that._drawedPoints || [], function(i, p) {
p.animate(i === lastPointIndex ? labelAnimFunc : undefined, {
r: p.bubbleSize,
translate: {
x: p.x,
y: p.y
}
})
})
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file pieSeries.js */
(function($, DX) {
var viz = DX.viz,
mixins = viz.core.series.mixins,
pieSeries = mixins.pieChart,
utils = DX.utils,
scatterSeries = mixins.chart.scatter,
barSeries = mixins.chart.bar,
_extend = $.extend,
_each = $.each,
_noop = $.noop,
_map = $.map,
_isFinite = isFinite,
_max = Math.max;
pieSeries.pie = _extend({}, barSeries, {
_createLabelGroup: scatterSeries._createLabelGroup,
_createGroups: scatterSeries._createGroups,
_drawPoint: function(point) {
scatterSeries._drawPoint.apply(this, arguments);
!point.isVisible() && point.setInvisibility()
},
_applyTrackersClippings: _noop,
_processRange: _noop,
_applyElementsClipRect: _noop,
_updateDataType: _noop,
getColor: _noop,
_prepareSeriesToDrawing: _noop,
_endUpdateData: scatterSeries._prepareSeriesToDrawing,
resetLabelEllipsis: function() {
_each(this._points || [], function(_, point) {
point._label.setLabelEllipsis = false
})
},
_adjustLabels: function(firstDrawing) {
var that = this,
options = that._options,
canvas = that.canvas,
points = that._points || [],
labelsBBoxes = [],
labelsSpaces = [],
labelSpace = 0,
maxLabelLength,
paneSpaceHeight,
paneSpaceWidth,
min;
if (options.label.position !== "inside") {
_each(points, function(_, point) {
if (point._label.hasText())
labelsBBoxes.push(point._label.getTextCoords().width)
});
if (labelsBBoxes.length) {
maxLabelLength = _max.apply(null, labelsBBoxes);
_each(points, function(_, point) {
if (point._label.hasText()) {
point._label.updatePosition(maxLabelLength);
point._label.setLabelEllipsis = true
}
});
that._firstDrawing = !that.redraw && firstDrawing;
that.redraw = true
}
}
else
_each(points, function(i, point) {
if (point._label.hasText()) {
point._label.setLabelEllipsis = true;
point._label.updatePosition()
}
})
},
_getCreatingPointOptions: function() {
return this._getPointOptions()
},
_updateOptions: function(options) {
this.labelSpace = 0;
this.innerRadius = this.type === "pie" ? 0 : options.innerRadius;
this.redraw = false
},
_checkData: function(data) {
var base = barSeries._checkData(data);
return this._options.paintNullPoints ? base : base && data.value !== null
},
_createMarkerGroup: function() {
if (!this._markersGroup)
this._markersGroup = this._renderer.createGroup({"class": "dxc-markers"}).append(this._group)
},
_getMainColor: function() {
return this._options.mainSeriesColor()
},
_getPointOptions: function() {
return this._parsePointOptions(this._preparePointOptions(), this._options.label)
},
_getRangeData: function() {
return this._rangeData
},
_getArrangeTotal: function(points) {
var total = 0;
_each(points, function(_, point) {
if (point.isVisible())
total += point.initialValue
});
return total
},
_createPointStyles: function(pointOptions) {
var mainColor = pointOptions.color || this._getMainColor(),
specialMainColor = this._getSpecialColor(mainColor);
return {
normal: this._parsePointStyle(pointOptions, mainColor, mainColor),
hover: this._parsePointStyle(pointOptions.hoverStyle, specialMainColor, mainColor),
selection: this._parsePointStyle(pointOptions.selectionStyle, specialMainColor, mainColor),
legendStyles: {
normal: this._createLegendState(pointOptions, mainColor),
hover: this._createLegendState(pointOptions.hoverStyle, specialMainColor),
selection: this._createLegendState(pointOptions.selectionStyle, specialMainColor)
}
}
},
_getArrangeMinShownValue: function(points, total) {
var minSegmentSize = this._options.minSegmentSize,
totalMinSegmentSize = 0,
totalNotMinValues = 0;
total = total || points.length;
_each(points, function(_, point) {
if (point.isVisible())
if (point.initialValue < minSegmentSize * total / 360)
totalMinSegmentSize += minSegmentSize;
else
totalNotMinValues += point.initialValue
});
return totalMinSegmentSize < 360 ? minSegmentSize * totalNotMinValues / (360 - totalMinSegmentSize) : 0
},
_applyArrangeCorrection: function(points, minShownValue, total) {
var options = this._options,
isClockWise = options.segmentsDirection !== "anticlockwise",
shiftedAngle = _isFinite(options.startAngle) ? utils.normalizeAngle(options.startAngle) : 0,
minSegmentSize = options.minSegmentSize,
percent,
correction = 0,
zeroTotalCorrection = 0;
if (total === 0) {
total = points.length;
zeroTotalCorrection = 1
}
_each(isClockWise ? points : points.concat([]).reverse(), function(_, point) {
var val = point.isVisible() ? zeroTotalCorrection || point.initialValue : 0,
updatedZeroValue;
if (minSegmentSize && point.isVisible() && val < minShownValue)
updatedZeroValue = minShownValue;
percent = val / total;
point.correctValue(correction, percent, zeroTotalCorrection + (updatedZeroValue || 0));
point.shiftedAngle = shiftedAngle;
correction = correction + (updatedZeroValue || val)
});
this._rangeData = {val: {
min: 0,
max: correction
}}
},
arrangePoints: function() {
var that = this,
minSegmentSize = that._options.minSegmentSize,
minShownValue,
pointIndex = 0,
total,
points = that._originalPoints = that._points = _map(that._originalPoints || [], function(point) {
if (point.value === null || point.value < 0 || point.value === 0 && !minSegmentSize) {
point.dispose();
return null
}
else {
point.index = pointIndex++;
return point
}
});
total = that._getArrangeTotal(points);
if (minSegmentSize)
minShownValue = this._getArrangeMinShownValue(points, total);
that._applyArrangeCorrection(points, minShownValue, total)
},
correctPosition: function(correction) {
var debug = DX.utils.debug;
debug.assert(correction, "correction was not passed");
debug.assertParam(correction.centerX, "correction.centerX was not passed");
debug.assertParam(correction.centerY, "correction.centerY was not passed");
debug.assertParam(correction.radiusInner, "correction.radiusInner was not passed");
debug.assertParam(correction.radiusOuter, "correction.radiusOuter was not passed");
_each(this._points, function(_, point) {
point.correctPosition(correction)
})
},
_animate: function(firstDrawing) {
var that = this,
index = 0,
timeThreshold = 0.2,
points = that._points,
pointsCount = points && points.length,
duration = 1 / (timeThreshold * (pointsCount - 1) + 1),
animateP = function() {
points[index] && points[index++].animate(index === pointsCount ? completeFunc : undefined, duration, stepFunc)
},
stepFunc = function(_, progress) {
if (progress >= timeThreshold) {
this.step = null;
animateP()
}
},
completeFunc = function() {
that._labelsGroup && that._labelsGroup.animate({opacity: 1}, {duration: 400})
};
if (firstDrawing)
animateP();
else
$.each(points, function(i, p) {
p.animate(i == pointsCount - 1 ? completeFunc : undefined)
})
},
getVisiblePoints: function() {
return _map(this._points, function(p) {
return p.isVisible() ? p : null
})
},
_beginUpdateData: function() {
this._deletePatterns();
this._patterns = []
}
});
pieSeries.doughnut = pieSeries.donut = pieSeries.pie
})(jQuery, DevExpress);
/*! Module viz-core, file financialSeries.js */
(function($, DX) {
var viz = DX.viz,
series = viz.core.series.mixins.chart,
scatterSeries = series.scatter,
barSeries = series.bar,
rangeCalculator = viz.core.series.helpers.rangeDataCalculator(),
_isDefined = DX.utils.isDefined,
_extend = $.extend,
_each = $.each,
_noop = $.noop,
DEFAULT_FINANCIAL_POINT_SIZE = 10;
series.stock = _extend({}, scatterSeries, {
_animate: _noop,
_applyMarkerClipRect: series.line._applyElementsClipRect,
_applyTrackersClippings: barSeries._applyTrackersClippings,
_createPattern: barSeries._createPattern,
_preparePointOptions: barSeries._preparePointOptions,
_createMarkerGroup: function() {
var that = this,
markersGroup,
styles = that._getPointOptions().styles,
defaultStyle = styles.normal,
defaultPositiveStyle = styles.positive.normal,
reductionStyle = styles.reduction.normal,
reductionPositiveStyle = styles.reductionPositive.normal,
markerSettings = {"class": "dxc-markers"};
that._applyMarkerClipRect(markerSettings);
defaultStyle["class"] = "default-markers";
defaultPositiveStyle["class"] = "default-positive-markers";
reductionStyle["class"] = "reduction-markers";
reductionPositiveStyle["class"] = "reduction-positive-markers";
that._createGroup("_markersGroup", that, that._group, markerSettings);
markersGroup = that._markersGroup;
that._createGroup("defaultMarkersGroup", markersGroup, markersGroup, defaultStyle);
that._createGroup("reductionMarkersGroup", markersGroup, markersGroup, reductionStyle);
that._createGroup("defaultPositiveMarkersGroup", markersGroup, markersGroup, defaultPositiveStyle);
that._createGroup("reductionPositiveMarkersGroup", markersGroup, markersGroup, reductionPositiveStyle)
},
_createGroups: function() {
scatterSeries._createGroups.call(this, false)
},
_clearingAnimation: function(translators, drawComplete) {
drawComplete()
},
_getCreatingPointOptions: function() {
if (!this._predefinedPointOptions) {
var styles,
defaultPointOptions = this._getPointOptions(),
strokeWidth = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.strokeWidth,
creatingPointOptions = _extend(true, {}, defaultPointOptions);
creatingPointOptions.styles = styles = creatingPointOptions.styles || {};
styles.normal = styles.positive.normal = styles.reduction.normal = styles.reductionPositive.normal = {strokeWidth: strokeWidth};
this._predefinedPointOptions = creatingPointOptions
}
return this._predefinedPointOptions
},
_checkData: function(data) {
return _isDefined(data.argument) && data.highValue !== undefined && data.lowValue !== undefined && data.openValue !== undefined && data.closeValue !== undefined
},
_processRange: function(point, prevPoint) {
rangeCalculator.processTwoValues(this, point, prevPoint, "highValue", "lowValue")
},
_getRangeData: function(zoomArgs, calcIntervalFunction) {
rangeCalculator.calculateTwoValuesRangeData(this, zoomArgs, calcIntervalFunction, "highValue", "lowValue");
rangeCalculator.addRangeSeriesLabelPaddings(this);
return this._rangeData
},
_getPointData: function(data, options) {
var that = this,
level,
argumentField = options.argumentField || "date",
tagField = options.tagField || "tag",
openValueField = options.openValueField || "open",
closeValueField = options.closeValueField || "close",
highValueField = options.highValueField || "high",
lowValueField = options.lowValueField || "low",
reductionValue;
that.level = options.reduction.level;
switch ((that.level || "").toLowerCase()) {
case"open":
level = openValueField;
break;
case"high":
level = highValueField;
break;
case"low":
level = lowValueField;
break;
default:
level = closeValueField;
that.level = "close";
break
}
reductionValue = data[level];
return {
argument: data[argumentField],
highValue: data[highValueField],
lowValue: data[lowValueField],
closeValue: data[closeValueField],
openValue: data[openValueField],
reductionValue: reductionValue,
tag: data[tagField],
isReduction: this._checkReduction(reductionValue)
}
},
_parsePointStyle: function(style, defaultColor, innerColor) {
return {
stroke: style.color || defaultColor,
strokeWidth: style.width,
fill: style.color || innerColor
}
},
updateTeamplateFieldNames: function() {
var that = this,
options = that._options,
valueFields = that.getValueFields(),
name = that.name;
options.openValueField = valueFields[0] + name;
options.highValueField = valueFields[1] + name;
options.lowValueField = valueFields[2] + name;
options.closeValueField = valueFields[3] + name;
options.tagField = that.getTagField() + name
},
_getDefaultStyle: function(options) {
var mainPointColor = options.color || this._options.mainSeriesColor;
return {
normal: this._parsePointStyle(options, mainPointColor, mainPointColor),
hover: this._parsePointStyle(options.hoverStyle, mainPointColor, mainPointColor),
selection: this._parsePointStyle(options.selectionStyle, mainPointColor, mainPointColor)
}
},
_getReductionStyle: function(options) {
var reductionColor = options.reduction.color,
normalStyle = this._parsePointStyle({
color: reductionColor,
width: options.width,
hatching: options.hatching
}, reductionColor, reductionColor);
return {
normal: normalStyle,
hover: this._parsePointStyle(options.hoverStyle, reductionColor, reductionColor),
selection: this._parsePointStyle(options.selectionStyle, reductionColor, reductionColor)
}
},
_createPointStyles: function(pointOptions) {
var that = this,
innerColor = that._options.innerColor,
styles = that._getDefaultStyle(pointOptions),
positiveStyle,
reductionStyle,
reductionPositiveStyle;
positiveStyle = _extend(true, {}, styles);
reductionStyle = that._getReductionStyle(pointOptions);
reductionPositiveStyle = _extend(true, {}, reductionStyle);
positiveStyle.normal.fill = positiveStyle.hover.fill = positiveStyle.selection.fill = innerColor;
reductionPositiveStyle.normal.fill = reductionPositiveStyle.hover.fill = reductionPositiveStyle.selection.fill = innerColor;
styles.positive = positiveStyle;
styles.reduction = reductionStyle;
styles.reductionPositive = reductionPositiveStyle;
return styles
},
_endUpdateData: function() {
delete this.prevLevelValue;
delete this._predefinedPointOptions
},
_checkReduction: function(value) {
var result = false;
if (value != null) {
if (_isDefined(this.prevLevelValue))
result = value < this.prevLevelValue;
this.prevLevelValue = value
}
return result
},
_fusionPoints: function(fusionPoints, tick, nowIndexTicks) {
var fusedPointData = {},
reductionLevel,
highValue = -Infinity,
lowValue = +Infinity,
openValue,
closeValue;
if (!fusionPoints.length)
return {};
_each(fusionPoints, function(_, point) {
if (!point.hasValue())
return;
highValue = Math.max(highValue, point.highValue);
lowValue = Math.min(lowValue, point.lowValue);
openValue = openValue !== undefined ? openValue : point.openValue;
closeValue = point.closeValue !== undefined ? point.closeValue : closeValue
});
fusedPointData.argument = tick;
fusedPointData.openValue = openValue;
fusedPointData.closeValue = closeValue;
fusedPointData.highValue = highValue;
fusedPointData.lowValue = lowValue;
fusedPointData.tag = null;
switch ((this.level || "").toLowerCase()) {
case"open":
reductionLevel = openValue;
break;
case"high":
reductionLevel = highValue;
break;
case"low":
reductionLevel = lowValue;
break;
default:
reductionLevel = closeValue;
break
}
fusedPointData.reductionValue = reductionLevel;
fusedPointData.isReduction = this._checkReduction(reductionLevel);
return fusedPointData
},
_getPointSize: function() {
return DEFAULT_FINANCIAL_POINT_SIZE
},
getValueFields: function() {
var options = this._options;
return [options.openValueField || "open", options.highValueField || "high", options.lowValueField || "low", options.closeValueField || "close"]
},
getArgumentField: function() {
return this._options.argumentField || "date"
}
});
series.candlestick = _extend({}, series.stock, {_parsePointStyle: function(style, defaultColor, innerColor) {
var color = this._createPattern(style.color || innerColor, style.hatching),
base = series.stock._parsePointStyle.call(this, style, defaultColor, color);
base.fill = color;
return base
}})
})(jQuery, DevExpress);
/*! Module viz-core, file stackedSeries.js */
(function($, DX) {
var viz = DX.viz,
series = viz.core.series.mixins.chart,
areaSeries = series.area,
barSeries = series.bar,
lineSeries = series.line,
rangeCalculator = viz.core.series.helpers.rangeDataCalculator(),
_extend = $.extend,
_noop = $.noop,
baseStackedSeries = {
_processRange: _noop,
_processStackedRange: function() {
var that = this,
prevPoint;
$.each(that.getAllPoints(), function(i, p) {
rangeCalculator.processRange(that, p, prevPoint);
prevPoint = p
})
},
_getRangeData: function() {
this._processStackedRange();
return areaSeries._getRangeData.apply(this, arguments)
}
},
baseFullStackedSeries = _extend({}, baseStackedSeries, {
_getRangeData: function(zoomArgs, calcIntervalFunction) {
this._processStackedRange();
rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
rangeCalculator.addLabelPaddings(this);
rangeCalculator.processFullStackedRange(this);
rangeCalculator.calculateRangeMinValue(this, zoomArgs);
return this._rangeData
},
isFullStackedSeries: function() {
return true
}
});
series.stackedline = _extend({}, lineSeries, baseStackedSeries, {_getRangeData: function() {
this._processStackedRange();
return lineSeries._getRangeData.apply(this, arguments)
}});
series.fullstackedline = _extend({}, lineSeries, baseFullStackedSeries, {_getRangeData: function(zoomArgs, calcIntervalFunction) {
this._processStackedRange();
var rangeCalculator = viz.core.series.helpers.rangeDataCalculator();
rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
rangeCalculator.addLabelPaddings(this);
rangeCalculator.processFullStackedRange(this);
return this._rangeData
}});
series.stackedbar = _extend({}, barSeries, baseStackedSeries, {_getRangeData: function() {
this._processStackedRange();
return barSeries._getRangeData.apply(this, arguments)
}});
series.fullstackedbar = _extend({}, barSeries, baseFullStackedSeries, {_getRangeData: function(zoomArgs, calcIntervalFunction) {
var rangeData = baseFullStackedSeries._getRangeData.apply(this, arguments);
rangeData.arg.stick = false;
return rangeData
}});
series.stackedarea = _extend({}, areaSeries, baseStackedSeries);
series.fullstackedarea = _extend({}, areaSeries, baseFullStackedSeries)
})(jQuery, DevExpress);
/*! Module viz-core, file basePoint.js */
(function($, DX) {
var viz = DX.viz,
statesConsts = viz.core.series.helpers.consts.states,
_each = $.each,
_extend = $.extend,
_isDefined = DX.utils.isDefined,
_noop = $.noop,
pointTypes = {
scatter: "symbolPoint",
line: "symbolPoint",
spline: "symbolPoint",
stepline: "symbolPoint",
stackedline: "symbolPoint",
fullstackedline: "symbolPoint",
area: "symbolPoint",
splinearea: "symbolPoint",
steparea: "symbolPoint",
stackedarea: "symbolPoint",
fullstackedarea: "symbolPoint",
rangearea: "rangeSymbolPoint",
bar: "barPoint",
stackedbar: "barPoint",
fullstackedbar: "barPoint",
rangebar: "rangeBarPoint",
bubble: "bubblePoint",
pie: "piePoint",
doughnut: "piePoint",
donut: "piePoint",
stock: "stockPoint",
candlestick: "candlestickPoint"
};
viz.core.series.points = {};
viz.core.series.points.Point = DX.Class.inherit({
ctor: function(dataItem, options) {
this.update(dataItem, options);
this._emptySettings = {
fill: null,
stroke: null,
dashStyle: null
}
},
getColor: function() {
return this._styles.normal.fill || this.series.getColor()
},
_getStyle: function() {
var styles = this._styles,
style;
if (this.isSelected())
style = styles.selection;
else if (this.isHovered())
style = styles.hover;
else {
this.fullState = statesConsts.normalMark;
style = styles.normal
}
return style
},
update: function(dataItem, options) {
this.updateOptions(options);
this.updateData(dataItem)
},
updateData: function(dataItem) {
this._updateData(dataItem);
if (!this.hasValue())
this.setInvisibility();
else {
this._updateLabelData();
this._fillStyle()
}
},
deleteMarker: function() {
this.graphic && this.graphic.detach();
this.graphic = null
},
deleteTrackerMarker: function() {
this.trackerGraphic && this.trackerGraphic.remove();
this.trackerGraphic = null
},
draw: function(renderer, markersGroup, labelsGroup, animationEnabled, firstDrawing) {
if (this._needDeletingOnDraw) {
this.deleteMarker();
this.deleteTrackerMarker();
this._needDeletingOnDraw = false
}
if (this._needClearingOnDraw) {
this.clearMarker();
this._needClearingOnDraw = false
}
if (!this._hasGraphic())
this._options.visible && this._drawMarker(renderer, markersGroup, animationEnabled, firstDrawing);
else
this._updateMarker(animationEnabled, undefined, markersGroup);
this._drawLabel(renderer, labelsGroup)
},
applyStyle: function(style) {
if (this.graphic) {
if (style === "normal")
this.clearMarker();
else
this.graphic.toForeground();
this._updateMarker(true, this._styles[style])
}
},
setHoverState: function() {
this.series.setPointHoverState(this)
},
releaseHoverState: function(callback) {
this.series.releasePointHoverState(this, callback);
if (this.graphic)
!this.isSelected() && this.graphic.toBackground()
},
setSelectedState: function() {
this.series.setPointSelectedState(this)
},
releaseSelectedState: function() {
this.series.releasePointSelectedState(this)
},
select: function() {
this.series.selectPoint(this)
},
clearSelection: function() {
this.series.deselectPoint(this)
},
showTooltip: function() {
this.series.showPointTooltip(this)
},
hideTooltip: function() {
this.series.hidePointTooltip(this)
},
_checkLabelsChanging: function(oldType, newType) {
if (oldType) {
var isNewRange = ~newType.indexOf("range"),
isOldRange = ~oldType.indexOf("range");
return isOldRange && !isNewRange || !isOldRange && isNewRange
}
else
return false
},
updateOptions: function(newOptions) {
if (!_isDefined(newOptions))
return;
var that = this,
oldOptions = that._options,
oldType = oldOptions && oldOptions.type,
newType = newOptions.type;
if (pointTypes[oldType] !== pointTypes[newType]) {
that._needDeletingOnDraw = true;
that._needClearingOnDraw = false;
that._checkLabelsChanging(oldType, newType) && that.deleteLabel();
that._resetType(oldType);
that._setType(newType)
}
else {
that._needDeletingOnDraw = that._checkSymbol(oldOptions, newOptions);
that._needClearingOnDraw = that._checkCustomize(oldOptions, newOptions)
}
that.series = newOptions.series;
that._options = newOptions;
that._fillStyle();
that._updateLabelOptions(pointTypes[newType])
},
translate: function(translators) {
this.translators = translators || this.translators;
this.translators && this.hasValue() && this._translate(this.translators)
},
drawTracker: function(renderer, group) {
if (!this.trackerGraphic)
this._drawTrackerMarker(renderer, group);
else
this._updateTracker()
},
_checkCustomize: function(oldOptions, newOptions) {
return oldOptions.styles.usePointCustomOptions && !newOptions.styles.usePointCustomOptions
},
_getCustomLabelVisibility: function() {
if (this._styles.useLabelCustomOptions)
return this._options.label.visible ? "visible" : "hidden"
},
_getGraphicSettings: function() {
return {
x: this.graphic.settings.x || 0,
y: this.graphic.settings.y || 0,
height: this.graphic.settings.height || 0,
width: this.graphic.settings.width || 0
}
},
_resetType: function(type) {
var that = this;
if (type)
_each(viz.core.series.points.mixins[pointTypes[type]], function(methodName) {
delete that[methodName]
})
},
_setType: function(type) {
var that = this;
_each(viz.core.series.points.mixins[pointTypes[type]], function(methodName, method) {
that[methodName] = method
})
},
_prepareStatesOptions: function() {
var that = this;
if (that._options.states && that._options.states.normal)
that._populatePointShape(that._options.states.normal.r)
},
isInVisibleArea: function() {
return this.inVisibleArea
},
isSelected: function() {
return !!(this.fullState & statesConsts.selectedMark)
},
isHovered: function() {
return !!(this.fullState & statesConsts.hoverMark)
},
getOptions: function() {
return this._options
},
animate: function(complete, settings, partitionDuration) {
if (!this.graphic) {
complete && complete();
return
}
this.graphic.animate(settings, {partitionDuration: partitionDuration}, complete)
},
getCoords: function(min) {
if (!min)
return {
x: this.x,
y: this.y
};
if (!this._options.rotated)
return {
x: this.x,
y: this.minY
};
return {
x: this.minX,
y: this.y
}
},
getDefaultCoords: function() {
return !this._options.rotated ? {
x: this.x,
y: this.defaultY
} : {
x: this.defaultX,
y: this.y
}
},
_calculateVisibility: function(x, y, width, height) {
var that = this,
visibleAreaX,
visibleAreaY,
rotated = that._options.rotated;
if (that.translators) {
visibleAreaX = that.translators.x.getCanvasVisibleArea();
visibleAreaY = that.translators.y.getCanvasVisibleArea();
if (visibleAreaX.min > x + (width || 0) || visibleAreaX.max < x || visibleAreaY.min > y + (height || 0) || visibleAreaY.max < y || rotated && _isDefined(width) && width !== 0 && (visibleAreaX.min === x + width || visibleAreaX.max === x) || !rotated && _isDefined(height) && height !== 0 && (visibleAreaY.min === y + height || visibleAreaY.max === y))
that.inVisibleArea = false;
else
that.inVisibleArea = true
}
},
correctPosition: _noop,
hasValue: function() {
return this.value !== null && this.minValue !== null
},
_populatePointShape: _noop,
_checkSymbol: _noop,
hide: _noop,
show: _noop,
hideMarker: _noop,
setInvisibility: _noop,
clearVisibility: _noop,
isVisible: _noop,
resetCorrection: _noop,
correctValue: _noop,
setPercentValue: _noop,
correctCoordinates: _noop,
dispose: function() {
this.deleteMarker();
this.deleteTrackerMarker();
this.deleteLabel();
this._options = null;
this._styles = null;
this.series = null;
this.translators = null
},
getTooltipFormatObject: function(tooltip) {
var that = this,
tooltipFormatObject = that._getFormatObject(tooltip),
sharedTooltipValuesArray = [],
tooltipStackPointsFormatObject = [];
if (that.stackPoints) {
_each(that.stackPoints, function(_, point) {
if (!point.isVisible())
return;
var formatObject = point._getFormatObject(tooltip);
tooltipStackPointsFormatObject.push(point._getFormatObject(tooltip));
sharedTooltipValuesArray.push(formatObject.seriesName + ": " + formatObject.valueText)
});
_extend(tooltipFormatObject, {
points: tooltipStackPointsFormatObject,
valueText: sharedTooltipValuesArray.join("\n"),
stackName: that.stackPoints.stackName
})
}
return tooltipFormatObject
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file label.js */
(function($, DX) {
var _isDefined = DX.utils.isDefined,
_extend = $.extend,
_math = Math,
_round = _math.round,
_floor = _math.floor,
_isEmptyObject = $.isEmptyObject,
_noop = $.noop,
LABEL_BACKGROUND_PADDING_X = 8,
LABEL_BACKGROUND_PADDING_Y = 4,
LABEL_OFFSET = 10,
setPositionFuncCollection = {
symbolPoint: "_setPositionForSymbol",
barPoint: "_setPositionForBar",
bubblePoint: "_setPositionForBubble",
rangeSymbolPoint: "_setPositionForSymbol",
rangeBarPoint: "_setPositionForBar",
stockPoint: "_setPositionForFinancial",
candlestickPoint: "_setPositionForFinancial"
},
checkPositionFuncCollection = {
symbolPoint: "_checkPositionForSymbol",
barPoint: "_checkPositionForBar",
bubblePoint: "_checkPositionForSymbol",
rangeSymbolPoint: "_checkPositionForSymbol",
rangeBarPoint: "_checkPositionForBar",
stockPoint: "_checkPositionForBar",
candlestickPoint: "_checkPositionForBar"
};
DX.viz.core.series.points.Label = DX.Class.inherit({
ctor: function(data, options) {
this._offset = LABEL_OFFSET;
this.updateData(data);
this.setOptions(options)
},
clearVisibility: function() {
if (this._group && this._group.settings.visibility)
this._group.applySettings({visibility: null})
},
hide: function() {
if (this._group && this._group.settings.visibility !== "hidden")
this._group.applySettings({visibility: "hidden"})
},
updateData: function(data) {
if (_isDefined(data)) {
this._data = data.formatObject;
this._initialValue = data.initialValue
}
},
updateOptions: function(options) {
this.setOptions(_extend(true, {}, {options: this._options}, options))
},
setOptions: function(newOptions) {
var that = this,
oldOptions = that._options,
newOptions = newOptions || {},
pointType = newOptions.type || "symbolPoint";
that._options = newOptions.options;
that._rotated = newOptions.rotated;
that._isFullStacked = newOptions.isFullStacked;
that._isRange = newOptions.isRange;
that._setPosition = that[setPositionFuncCollection[pointType]];
that._checkPosition = that[checkPositionFuncCollection[pointType]];
if (oldOptions) {
that._isBackgroundChanged(oldOptions.background, that._options.background) && that._deleteBackground();
that._isConnectorChanged(oldOptions.connector, that._options.connector) && that._deleteConnector()
}
},
setDataField: function(fieldName, fieldValue) {
this._data = this._data || {};
this._data[fieldName] = fieldValue
},
getData: function() {
return this._data
},
setCoords: function(coords, graphicBbox, location, visibleArea) {
this._coords = coords;
this._graphicBbox = graphicBbox;
this._visibleArea = visibleArea;
this._location = location
},
hasText: function() {
return !!this._text
},
getTextCoords: function() {
return this._text && this._text.getBBox()
},
getCoords: function() {
var coords = {},
insideGroup = this._insideGroup;
if (insideGroup) {
coords = insideGroup.getBBox();
coords.x = insideGroup.settings.translateX || 0;
coords.y = insideGroup.settings.translateY || 0
}
return coords
},
updatePosition: function(x, y) {
var settings = {},
insideGroup = this._insideGroup;
insideGroup.applySettings({
translateX: x,
translateY: y
});
this._connector && this._drawConnector()
},
_deleteElements: function() {
this._deleteConnector();
this._deleteBackground();
this._deleteText();
this._deleteGroups()
},
dispose: function() {
this._data = null;
this._options = null;
this._positioningFunction = null;
this._graphicBbox = null;
this._visibleArea = null;
this._coords = null;
this._deleteElements()
},
_deleteText: function() {
this._text && this._text.detach();
this._text = null
},
_deleteGroups: function() {
this._insideGroup = null;
this._group && this._group.detach();
this._group = null
},
_drawGroups: function(renderer, group) {
if (!this._group)
this._group = renderer.createGroup().append(group);
if (!this._insideGroup)
this._insideGroup = renderer.createGroup().append(this._group)
},
_drawText: function(renderer, text) {
if (!this._text)
this._text = renderer.createText(text, 0, 0, this._options.attributes).append(this._insideGroup);
else
this._text.applySettings({text: text}, this._options.attributes)
},
_drawBackground: function(renderer) {
var that = this,
options = that._options,
background = options.background || {},
settings;
if (that._checkBackground(background)) {
settings = _extend(that._getBackgroundSettings(), background);
if (!that._background)
that._background = renderer.createRect(settings.x, settings.y, settings.width, settings.height, 0, background).append(that._insideGroup);
else
that._background.applySettings(settings);
that._background.toBackground()
}
},
_drawConnector: function(renderer) {
var that = this,
connector = that._options.connector || {},
points;
if (that._checkConnector(connector)) {
points = that._getConnectorPoints() || [];
if (!that._connector)
that._connector = renderer.createPath(points, connector).append(that._group);
else
that._connector.applySettings(_extend({points: points}, connector));
that._connector.toBackground()
}
},
_setVisibility: function(visibility) {
this._group && this._group.applySettings({visibility: visibility})
},
draw: function(renderer, group, visibility) {
var that = this,
options = that._options,
background = options.background,
text = that._format();
if (_isDefined(text) && text !== "") {
that._drawGroups(renderer, group);
that._setVisibility(visibility);
that._drawText(renderer, text);
that._drawBackground(renderer);
that._rotateLabel();
that._setPosition();
that._drawConnector(renderer)
}
else
that._setVisibility("hidden")
},
_deleteBackground: function() {
this._background && this._background.detach();
this._background = null
},
_isBackgroundChanged: function(oldBackground, newBackground) {
return this._checkBackground(oldBackground || {}) !== this._checkBackground(newBackground || {})
},
_checkBackground: function(background) {
var hasColor = background.fill && background.fill !== "none",
hasBorder = background.strokeWidth && background.stroke && background.stroke !== "none";
return hasColor || hasBorder
},
_getBackgroundSettings: function() {
var bbox = this._text.getBBox();
return {
x: bbox.x - LABEL_BACKGROUND_PADDING_X,
y: bbox.y - LABEL_BACKGROUND_PADDING_Y,
width: bbox.width + 2 * LABEL_BACKGROUND_PADDING_X,
height: bbox.height + 2 * LABEL_BACKGROUND_PADDING_Y
}
},
_deleteConnector: function() {
this._connector && this._connector.detach();
this._connector = null
},
_isConnectorChanged: function(oldConnector, newConnector) {
return this._checkConnector(oldConnector || {}) !== this._checkConnector(newConnector || {})
},
_checkConnector: function(connector) {
return connector && connector.strokeWidth
},
_getConnectorPoints: function() {
var that = this,
rotated = that._rotated,
labelBbox = that._insideGroup.getBBox(),
graphicBbox = that._graphicBbox,
centerLabelY,
centerLabelX,
rightLabelCoord,
bottomLabelCoord,
x1,
x2,
y1,
y2;
labelBbox.x += that._insideGroup.settings.translateX || 0;
labelBbox.y += that._insideGroup.settings.translateY || 0;
centerLabelY = that._background ? labelBbox.y + labelBbox.height / 2 : null;
centerLabelX = that._background ? labelBbox.x + labelBbox.width / 2 : null,
rightLabelCoord = labelBbox.x + labelBbox.width;
bottomLabelCoord = labelBbox.y + labelBbox.height;
x1 = _floor(labelBbox.x + labelBbox.width / 2);
x2 = _floor(graphicBbox.x + graphicBbox.width / 2);
if (bottomLabelCoord < graphicBbox.y) {
y1 = centerLabelY || bottomLabelCoord;
y2 = graphicBbox.y
}
else if (labelBbox.y > graphicBbox.y + graphicBbox.height) {
y1 = centerLabelY || labelBbox.y;
y2 = graphicBbox.y + graphicBbox.height
}
else {
if (labelBbox.x > graphicBbox.x + graphicBbox.width) {
x1 = centerLabelX || labelBbox.x;
x2 = graphicBbox.x + graphicBbox.width
}
else if (rightLabelCoord < graphicBbox.x) {
x1 = centerLabelX || rightLabelCoord;
x2 = graphicBbox.x
}
else
return;
y1 = _floor(labelBbox.y + labelBbox.height / 2);
y2 = _floor(graphicBbox.y + graphicBbox.height / 2)
}
return [{
x: x1,
y: y1
}, {
x: x2,
y: y2
}]
},
_rotateLabel: function() {
var bbox = this._insideGroup.getBBox();
this._insideGroup.rotate(this._options.rotationAngle)
},
_format: function() {
var that = this,
data = that._data,
options = that._options,
formatHelper = DX.formatHelper;
data.valueText = formatHelper.format(data.value, options.format, options.precision);
data.argumentText = formatHelper.format(data.argument, options.argumentFormat, options.argumentPrecision);
if (data.percent !== undefined)
data.percentText = formatHelper.format(data.percent, "percent", options.percentPrecision);
if (data.total !== undefined)
data.totalText = formatHelper.format(data.total, options.format, options.precision);
if (data.openValue !== undefined)
data.openValueText = formatHelper.format(data.openValue, options.format, options.precision);
if (data.closeValue !== undefined)
data.closeValueText = formatHelper.format(data.closeValue, options.format, options.precision);
if (data.lowValue !== undefined)
data.lowValueText = formatHelper.format(data.lowValue, options.format, options.precision);
if (data.highValue !== undefined)
data.highValueText = formatHelper.format(data.highValue, options.format, options.precision);
if (data.reductionValue !== undefined)
data.reductionValueText = formatHelper.format(data.reductionValue, options.format, options.precision);
return options.customizeText ? options.customizeText.call(data, data) : data.valueText
},
_getOutsideLabelCoords: function(labelBbox) {
var graphicBbox = this._graphicBbox,
x = 0,
y = 0,
isTop = this._location === "top";
if (!this._rotated) {
x += graphicBbox.width / 2 + graphicBbox.x;
if (isTop)
y += graphicBbox.y - labelBbox.y - labelBbox.height - this._offset;
else
y += graphicBbox.y + graphicBbox.height - labelBbox.y + this._offset
}
else {
y += graphicBbox.y - labelBbox.y - labelBbox.height / 2 + graphicBbox.height / 2;
if (isTop)
x += graphicBbox.x + graphicBbox.width - labelBbox.x + this._offset;
else
x += graphicBbox.x - labelBbox.x - labelBbox.width - this._offset
}
return {
x: x,
y: y
}
},
_getInsideLabelCoords: function(labelBbox) {
var graphicBbox = this._graphicBbox,
isTop = this._location === "top",
x = 0,
y = 0;
if (!this._isRange)
if (!this._rotated) {
x += graphicBbox.width / 2 + graphicBbox.x;
y += graphicBbox.y - labelBbox.y - labelBbox.height / 2 + graphicBbox.height / 2
}
else {
y += graphicBbox.y - labelBbox.y - labelBbox.height / 2 + graphicBbox.height / 2;
x += graphicBbox.x - labelBbox.x - labelBbox.width / 2 + graphicBbox.width / 2
}
else if (!this._rotated) {
x += graphicBbox.width / 2 + graphicBbox.x;
if (isTop)
y += graphicBbox.y - labelBbox.y - labelBbox.height + this._offset + labelBbox.height;
else
y += graphicBbox.y + graphicBbox.height - labelBbox.y - this._offset - labelBbox.height
}
else {
y += graphicBbox.y - labelBbox.y - labelBbox.height / 2 + graphicBbox.height / 2;
if (isTop)
x += graphicBbox.x + graphicBbox.width - labelBbox.x - labelBbox.width - this._offset;
else
x += graphicBbox.x - labelBbox.x + this._offset
}
return {
x: x,
y: y
}
},
_getFullstackedLabelCoords: function(labelBbox) {
var x = 0,
y = 0,
graphicBbox = this._graphicBbox;
if (!this._rotated) {
x += graphicBbox.width / 2 + graphicBbox.x;
y += this._coords.defaultY - labelBbox.y - labelBbox.height - this._offset
}
else {
y += graphicBbox.y - labelBbox.y - labelBbox.height / 2 + graphicBbox.height / 2;
x += this._coords.defaultX - labelBbox.x + this._offset
}
return {
x: x,
y: y
}
},
_setPositionForSymbol: function() {
var that = this,
offset = that._offset,
labelBBox = that._insideGroup.getBBox(),
graphicBbox = that._graphicBbox,
isTop = that._location === "top",
correctionY = 0,
correctionX = 0,
x = 0,
y = 0;
if (!that._rotated) {
correctionX = that._coords.x;
correctionY = isTop ? -labelBBox.y - labelBBox.height - offset : graphicBbox.height - labelBBox.y + offset;
correctionY += graphicBbox.y
}
else {
correctionY = graphicBbox.y - labelBBox.y - labelBBox.height / 2 + graphicBbox.height / 2;
correctionX = isTop ? graphicBbox.width - labelBBox.x + offset : -labelBBox.x - labelBBox.width - offset;
correctionX += graphicBbox.x
}
x += correctionX + that._options.horizontalOffset;
y += correctionY + that._options.verticalOffset;
that._checkPosition({
x: labelBBox.x + x,
y: labelBBox.y + y,
height: labelBBox.height,
width: labelBBox.width
}, x, y)
},
_checkPositionForSymbol: function(labelBbox, x, y) {
var that = this,
graphicBbox = that._graphicBbox,
visibleArea = that._visibleArea,
offset = that._offset;
if (!that._rotated) {
if (visibleArea.minX <= graphicBbox.x + graphicBbox.width && visibleArea.maxX >= graphicBbox.x) {
if (visibleArea.minX > labelBbox.x && that.adjustSeriesLabels)
x += visibleArea.minX - labelBbox.x;
if (visibleArea.maxX < labelBbox.x + labelBbox.width && that.adjustSeriesLabels)
x -= labelBbox.x + labelBbox.width - visibleArea.maxX;
if (visibleArea.minY > labelBbox.y)
y += graphicBbox.y + graphicBbox.height - labelBbox.y + offset;
if (visibleArea.maxY < labelBbox.y + labelBbox.height)
y -= labelBbox.y + labelBbox.height - graphicBbox.y + offset
}
}
else if (visibleArea.minY <= graphicBbox.y + graphicBbox.height && visibleArea.maxY >= graphicBbox.y) {
if (visibleArea.minX > labelBbox.x)
x += graphicBbox.x + graphicBbox.width - labelBbox.x + offset;
if (visibleArea.maxX < labelBbox.x + labelBbox.width)
x -= labelBbox.x + labelBbox.width - graphicBbox.x + offset;
if (visibleArea.minY > graphicBbox.y && that.adjustSeriesLabels)
y += visibleArea.minY - labelBbox.y;
if (visibleArea.maxY < labelBbox.y + labelBbox.height && that.adjustSeriesLabels)
y -= labelBbox.y + labelBbox.height - visibleArea.maxY
}
that._insideGroup.applySettings({
translateX: _round(x),
translateY: _round(y)
})
},
_setPositionForBar: function() {
var that = this,
offset = that._offset,
labelPosition = that._options.position,
labelBbox = that._insideGroup.getBBox(),
coords;
if (that._initialValue === 0 && that._isFullStacked)
coords = that._getFullstackedLabelCoords(labelBbox);
else if (labelPosition === "inside")
coords = that._getInsideLabelCoords(labelBbox);
else
coords = that._getOutsideLabelCoords(labelBbox);
coords.x += that._options.horizontalOffset;
coords.y += that._options.verticalOffset;
that._checkPosition({
x: labelBbox.x + coords.x,
y: labelBbox.y + coords.y,
height: labelBbox.height,
width: labelBbox.width
}, coords.x, coords.y)
},
_checkPositionForBar: function(labelBbox, x, y) {
var that = this,
graphicBbox = that._graphicBbox,
visibleArea = that._visibleArea;
if (visibleArea.minX <= graphicBbox.x + graphicBbox.width && visibleArea.maxX >= graphicBbox.x && visibleArea.minY <= graphicBbox.y + graphicBbox.height && visibleArea.maxY >= graphicBbox.y)
if (!that._rotated) {
if (visibleArea.minX > labelBbox.x && that.adjustSeriesLabels)
x += visibleArea.minX - labelBbox.x;
if (visibleArea.maxX < labelBbox.x + labelBbox.width && that.adjustSeriesLabels)
x -= labelBbox.x + labelBbox.width - visibleArea.maxX;
if (visibleArea.minY > labelBbox.y)
y += visibleArea.minY - labelBbox.y;
if (visibleArea.maxY < labelBbox.y + labelBbox.height)
y -= labelBbox.y + labelBbox.height - visibleArea.maxY
}
else {
if (visibleArea.minX > labelBbox.x)
x += visibleArea.minX - labelBbox.x;
if (visibleArea.maxX < labelBbox.x + labelBbox.width)
x -= labelBbox.x + labelBbox.width - visibleArea.maxX;
if (visibleArea.minY > labelBbox.y && that.adjustSeriesLabels)
y += visibleArea.minY - labelBbox.y;
if (visibleArea.maxY < labelBbox.y + labelBbox.height && that.adjustSeriesLabels)
y -= labelBbox.y + labelBbox.height - visibleArea.maxY
}
if (that._options.resolveLabelsOverlapping && that._options.position === "inside")
if (that._rotated) {
if (labelBbox.width > graphicBbox.width || labelBbox.height > graphicBbox.height) {
that.hide();
return
}
}
else if (labelBbox.height > graphicBbox.height || labelBbox.width > graphicBbox.width) {
that.hide();
return
}
that._insideGroup.applySettings({
translateX: _round(x),
translateY: _round(y)
})
},
_setPositionForBubble: function() {
var that = this,
labelBbox = that._insideGroup.getBBox(),
graphicBbox = that._graphicBbox,
x = 0,
y = 0;
if (that._options.position === "inside") {
x = that._coords.x;
y += graphicBbox.y + graphicBbox.height / 2 - labelBbox.y - labelBbox.height / 2;
x += that._options.horizontalOffset;
y += that._options.verticalOffset;
that._checkPosition({
x: labelBbox.x + x,
y: labelBbox.y + y,
height: labelBbox.height,
width: labelBbox.width
}, x, y)
}
else
that._setPositionForSymbol()
},
_setPositionForFinancial: function() {
var that = this,
offset = that._offset,
labelBbox = that._insideGroup.getBBox(),
coords;
coords = that._getOutsideLabelCoords(labelBbox);
coords.x += that._options.horizontalOffset;
coords.y += that._options.verticalOffset;
that._checkPosition({
x: labelBbox.x + coords.x,
y: labelBbox.y + coords.y,
height: labelBbox.height,
width: labelBbox.width
}, coords.x, coords.y)
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file pieLabel.js */
(function($, DX) {
var getCosAndSin = DX.utils.getCosAndSin,
_extend = $.extend,
_math = Math,
_round = _math.round,
_max = _math.max,
_inArray = $.inArray,
_isDefined = DX.utils.isDefined,
INDENT_FROM_PIE = 30,
CONNECTOR_LENGTH = 20;
DX.viz.core.series.points.PieLabel = DX.viz.core.series.points.Label.inherit({
ctor: function(data, options) {
this.setLabelEllipsis = false;
this.indentFromPie = INDENT_FROM_PIE;
this.updateData(data);
this.setOptions(options)
},
updateData: function(data) {
if (_isDefined(data))
this._data = data.formatObject
},
setOptions: function(newOptions) {
var that = this,
oldOptions = that._options,
newOptions = newOptions || {};
that._options = newOptions.options;
that._borderWidth = newOptions.borderWidth;
if (oldOptions) {
that._isBackgroundChanged(oldOptions.background, that._options.background) && that._deleteBackground();
that._isConnectorChanged(oldOptions.connector, that._options.connector) && that._deleteConnector()
}
},
setCoords: function(coords, canvas) {
this._middleAngle = coords.middleAngle;
this._radiusOuter = coords.radiusOuter;
this._centerX = coords.centerX;
this._centerY = coords.centerY;
this._canvas = canvas
},
updatePosition: function(maxLabelLength) {
this._setPosition(maxLabelLength);
this._checkEllipsis();
this._drawBackground();
this._rotateLabel();
this._checkPosition();
this._connector && this._drawConnector()
},
dispose: function() {
this._data = null;
this._options = null;
this._canvas = null;
this._deleteElements()
},
draw: function(renderer, group, visibility) {
var that = this,
options = that._options,
background = options.background,
text = that._format();
if (_isDefined(text) && text !== "") {
that._drawGroups(renderer, group);
that._setVisibility(visibility);
that._drawText(renderer, text);
that._setPosition();
that._checkEllipsis();
that._drawBackground(renderer);
that._rotateLabel();
that._checkPosition();
that._drawConnector(renderer)
}
else
that._setVisibility("hidden")
},
_getOutsideGroupLabelPosition: function() {
this._deleteConnector();
return this._group && this._group.getBBox()
},
_setPosition: function(maxLabelLength) {
var that = this,
bbox = that._text.getBBox(),
options = that._options,
angleFunctions = getCosAndSin(that._middleAngle),
align = "center",
rad = that._radiusOuter + options.radialOffset,
canvas = that._canvas,
rightBorderX = canvas.width - canvas.right,
leftBorderX = canvas.left,
x,
y;
if (options.position === 'inside') {
rad -= that.indentFromPie;
x = that._centerX + rad * angleFunctions.cos
}
else if (options.position === 'columns') {
rad += CONNECTOR_LENGTH;
if (angleFunctions.cos >= 0) {
align = "right";
x = maxLabelLength ? that._centerX + rad + maxLabelLength : rightBorderX;
x = x > rightBorderX ? rightBorderX : x
}
else if (angleFunctions.cos < 0) {
align = "left";
x = maxLabelLength ? that._centerX - rad - maxLabelLength : leftBorderX;
x = x < leftBorderX ? leftBorderX : x
}
}
else {
rad += that.indentFromPie;
if (angleFunctions.cos > 0.1)
align = "left";
else if (angleFunctions.cos < -0.1)
align = "right";
x = that._centerX + rad * angleFunctions.cos
}
y = _round(that._text.settings.y + that._centerY - rad * angleFunctions.sin - bbox.y - bbox.height / 2);
that._text.applySettings({
x: x,
y: y,
align: align
})
},
_getConnectorPoints: function() {
var that = this,
options = that._options,
position = options.position,
angleFunctions,
rad = that._radiusOuter,
box,
x,
y,
points = [];
if (position !== "inside") {
angleFunctions = getCosAndSin(_round(that._middleAngle));
points.push({
x: _round(that._centerX + (rad - that._borderWidth) * angleFunctions.cos),
y: _round(that._centerY - (rad - that._borderWidth) * angleFunctions.sin)
});
x = _round(that._centerX + (rad + options.radialOffset + CONNECTOR_LENGTH) * angleFunctions.cos);
if (position === "columns") {
box = that._insideGroup.getBBox();
box.x = box.x + (that._insideGroup.settings.translateX || 0);
box.y = box.y + (that._insideGroup.settings.translateY || 0);
y = box.y + box.height / 2;
points.push({
x: x,
y: y
});
if (that._background)
x = box.x + box.width / 2;
else if (angleFunctions.cos < 0)
x = box.x + box.width;
else if (angleFunctions.cos > 0)
x = box.x;
points.push({
x: x,
y: y
})
}
else {
y = _round(that._centerY - (rad + options.radialOffset + CONNECTOR_LENGTH) * angleFunctions.sin);
points.push({
x: x,
y: y
})
}
}
return points
},
_rotateLabel: function() {
var that = this,
options = that._options,
shift = that._radiusOuter + options.radialOffset * 2 + CONNECTOR_LENGTH,
angleFunctions = getCosAndSin(that._middleAngle),
x,
y,
box = that._insideGroup.getBBox();
if (options.position === "inside" || options.position === "columns") {
x = box.x + box.width / 2;
y = box.y + box.height / 2
}
else {
x = that._centerX + shift * angleFunctions.cos;
y = that._centerY - shift * angleFunctions.sin
}
that._insideGroup.applySettings({
x: x,
y: y,
rotate: options.rotationAngle
})
},
_checkEllipsis: function() {
var that = this,
i,
LABEL_OFFSET = 10,
labelBox,
text,
textLength = 0,
linesLength = [],
numLastSpan = [],
maxLength,
numSpan,
index,
x,
y,
width,
rotationAngleFunction = getCosAndSin(that._options.rotationAngle),
canvas = that._canvas,
labelOptions = that._options,
angleFunctions = getCosAndSin(that._middleAngle),
borderX = that._centerX + (that._radiusOuter + CONNECTOR_LENGTH) * angleFunctions.cos;
if (!that._text.tspans || !that.setLabelEllipsis)
return;
labelBox = that._text.getBBox();
x = labelBox.x + labelBox.width < that._centerX ? labelBox.x + labelBox.width : labelBox.x;
y = labelBox.y + labelBox.height / 2;
width = labelBox.x + labelBox.width < that._centerX ? -labelBox.width : labelBox.width;
if (y + width * rotationAngleFunction.sin > canvas.height - canvas.bottom + LABEL_OFFSET || y + width * rotationAngleFunction.sin < canvas.top - LABEL_OFFSET || x + width * rotationAngleFunction.cos < canvas.left - LABEL_OFFSET || x + width * rotationAngleFunction.cos > canvas.width - canvas.right + LABEL_OFFSET || labelOptions.position === "columns" && (angleFunctions.cos < 0 && borderX < x || angleFunctions.cos > 0 && borderX > x))
for (i = 0; i < that._text.tspans.length; i++) {
textLength += that._text.tspans[i].element.getNumberOfChars();
if (!that._text.tspans[i + 1] || that._text.tspans[i + 1].settings.dy > 0) {
linesLength.push(textLength);
numLastSpan.push(i);
textLength = 0
}
}
while (y + width * rotationAngleFunction.sin > canvas.height - canvas.bottom + LABEL_OFFSET || y + width * rotationAngleFunction.sin < canvas.top - LABEL_OFFSET || x + width * rotationAngleFunction.cos < canvas.left - LABEL_OFFSET || x + width * rotationAngleFunction.cos > canvas.width - canvas.right + LABEL_OFFSET || labelOptions.position === "columns" && (angleFunctions.cos < 0 && borderX < x || angleFunctions.cos > 0 && borderX > x)) {
maxLength = _max.apply(null, linesLength);
if (maxLength === 0)
break;
index = _inArray(maxLength, linesLength);
numSpan = numLastSpan[index];
if (that._text.tspans[numSpan].element.textContent === "...") {
if (that._text.tspans[numSpan].settings.dy > 0 || !that._text.tspans[numSpan - 1])
linesLength[index] = 0;
else if (that._text.tspans[numSpan - 1]) {
that._text.tspans[numSpan].element.textContent = "";
numLastSpan[index] -= 1;
that._text.tspans[numSpan - 1].element.textContent += "..."
}
}
else {
text = that._text.tspans[numSpan].element.textContent;
text = text.substr(0, text.length - 1 - 3) + "...";
that._text.tspans[numSpan].element.textContent = text;
linesLength[index] -= 1
}
labelBox = that._text.getBBox();
x = labelBox.x + labelBox.width < that._centerX ? labelBox.x + labelBox.width : labelBox.x;
y = labelBox.y + labelBox.height / 2;
width = labelBox.x + labelBox.width < that._centerX ? -labelBox.width : labelBox.width
}
},
_checkPosition: function() {
var that = this,
group = that._insideGroup,
box = group.getBBox(),
canvas = that._canvas,
x = 0,
y = 0;
if (box.y + box.height > canvas.height - canvas.bottom)
y = canvas.height - box.y - box.height - canvas.bottom;
else if (box.y < canvas.top)
y = canvas.top - box.y;
if (box.x + box.width > canvas.width - canvas.right)
x = canvas.width - canvas.right - box.x - box.width;
else if (box.x < canvas.left)
x = canvas.left - box.x;
group.applySettings({
translateX: x,
translateY: y
})
},
setPosition: function(position) {
this._options.position = position
},
getPosition: function() {
return this._options.position
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file symbolPoint.js */
(function($, DX) {
var viz = DevExpress.viz,
core = viz.core,
series = core.series,
_extend = $.extend,
_each = $.each,
_isNumber = DX.utils.isNumber,
_isDefined = DX.utils.isDefined,
_isEmptyObject = $.isEmptyObject,
_math = Math,
_round = _math.round,
_floor = _math.floor,
_ceil = _math.ceil,
DEFAULT_IMAGE_WIDTH = 20,
DEFAULT_IMAGE_HEIGHT = 20,
CANVAS_POSITION_DEFAULT = "canvas_position_default";
series.points.mixins = series.points.mixins || {};
series.points.mixins.symbolPoint = {
deleteLabel: function() {
this._label.dispose();
this._label = null
},
_hasGraphic: function() {
return this.graphic
},
_clearTrackerVisibility: function() {
if (this.trackerGraphic && this.trackerGraphic.settings.visibility)
this.trackerGraphic.applySettings({visibility: null})
},
clearVisibility: function() {
if (this.graphic && this.graphic.settings.visibility)
this.graphic.applySettings({visibility: null});
this._clearTrackerVisibility();
this._label.clearVisibility()
},
isVisible: function() {
return this.inVisibleArea && this.series.isVisible()
},
_setTrackerInvisibility: function() {
if (this.trackerGraphic && this.trackerGraphic.settings.visibility !== "hidden")
this.trackerGraphic.applySettings({visibility: "hidden"})
},
setInvisibility: function() {
if (this.graphic && this.graphic.settings.visibility !== "hidden")
this.graphic.applySettings({visibility: "hidden"});
this._setTrackerInvisibility();
this._label.hide()
},
clearMarker: function() {
this.graphic && this.graphic.applySettings(this._emptySettings)
},
setAdjustSeriesLabels: function(adjustSeriesLabels) {
this._label.adjustSeriesLabels = adjustSeriesLabels
},
_getLabelOptions: function(type) {
var options = this._options;
return {
options: options.label,
rotated: options.rotated,
type: type,
isFullStacked: options.series.isFullStackedSeries(),
isRange: options.type.indexOf("range") !== -1
}
},
_createLabel: function() {
this._label = core.CoreFactory.createLabel(this._options.type)
},
_updateLabelData: function() {
this._label.updateData({
formatObject: this._getLabelFormatObject(),
initialValue: this.initialValue
})
},
_updateLabelOptions: function(type) {
!this._label && this._createLabel();
this._label.setOptions(this._getLabelOptions(type))
},
_checkImage: function(image) {
return _isDefined(image) && (typeof image === "string" || _isDefined(image.url))
},
_fillStyle: function() {
this._styles = this._options.styles
},
_checkSymbol: function(oldOptions, newOptions) {
var oldSymbol = oldOptions.symbol,
newSymbol = newOptions.symbol,
symbolChanged = oldSymbol === "circle" && newSymbol !== "circle" || oldSymbol !== "circle" && newSymbol === "circle",
imageChanged = this._checkImage(oldOptions.image) !== this._checkImage(newOptions.image);
if (symbolChanged || imageChanged)
return true;
return false
},
_getSquareMarkerCoords: function(radius) {
return [{
x: -radius,
y: -radius
}, {
x: radius,
y: -radius
}, {
x: radius,
y: radius
}, {
x: -radius,
y: radius
}, {
x: -radius,
y: -radius
}]
},
_getPolygonMarkerCoords: function(radius) {
var r = _ceil(radius);
return [{
x: -r,
y: 0
}, {
x: 0,
y: -r
}, {
x: r,
y: 0
}, {
x: 0,
y: r
}, {
x: -r,
y: 0
}]
},
_getTriangleMarkerCoords: function(radius) {
return [{
x: -radius,
y: -radius
}, {
x: radius,
y: -radius
}, {
x: 0,
y: radius
}, {
x: -radius,
y: -radius
}]
},
_getCrossMarkerCoords: function(radius) {
var r = _ceil(radius),
floorHalfRadius = _floor(r / 2),
ceilHalfRadius = _ceil(r / 2);
return [{
x: -r,
y: -floorHalfRadius
}, {
x: -floorHalfRadius,
y: -r
}, {
x: 0,
y: -ceilHalfRadius
}, {
x: floorHalfRadius,
y: -r
}, {
x: r,
y: -floorHalfRadius
}, {
x: ceilHalfRadius,
y: 0
}, {
x: r,
y: floorHalfRadius
}, {
x: floorHalfRadius,
y: r
}, {
x: 0,
y: ceilHalfRadius
}, {
x: -floorHalfRadius,
y: r
}, {
x: -r,
y: floorHalfRadius
}, {
x: -ceilHalfRadius,
y: 0
}]
},
_populatePointShape: function(symbol, radius) {
switch (symbol) {
case"square":
return this._getSquareMarkerCoords(radius);
case"polygon":
return this._getPolygonMarkerCoords(radius);
case"triangle":
return this._getTriangleMarkerCoords(radius);
case"cross":
return this._getCrossMarkerCoords(radius)
}
},
correctValue: function(correction) {
if (this.hasValue()) {
this.value = this.initialValue + correction;
this.minValue = correction;
this.translate()
}
},
resetCorrection: function() {
this.value = this.initialValue;
this.minValue = CANVAS_POSITION_DEFAULT
},
_getTranslates: function(animationEnabled) {
var translateX,
translateY;
translateX = this.x;
translateY = this.y;
if (animationEnabled)
if (this._options.rotated)
translateX = this.defaultX;
else
translateY = this.defaultY;
return {
x: translateX,
y: translateY
}
},
_createImageMarker: function(renderer, settings, options) {
var url,
width,
height,
offsetY,
attr = {
location: "center",
translateX: settings.attr.translateX,
translateY: settings.attr.translateY,
visibility: settings.attr.visibility
};
url = options.url ? options.url.toString() : options.toString();
width = options.width || DEFAULT_IMAGE_WIDTH;
height = options.height || DEFAULT_IMAGE_HEIGHT;
return renderer.createImage(-_round(width * 0.5), -_round(height * 0.5), width, height, url, attr)
},
_createSymbolMarker: function(renderer, pointSettings, animationEnabled) {
var marker,
options = this._options;
switch (options.symbol) {
case"circle":
marker = renderer.createCircle(0, 0, pointSettings.r, pointSettings.attr);
break;
case"square":
case"polygon":
case"triangle":
case"cross":
marker = renderer.createArea(pointSettings.points, pointSettings.attr);
break
}
return marker
},
_createMarker: function(renderer, group, image, settings, animationEnabled) {
var marker = this._checkImage(image) ? this._createImageMarker(renderer, settings, image) : this._createSymbolMarker(renderer, settings, animationEnabled);
marker && marker.append(group);
return marker
},
_getSymbolBbox: function(x, y, r) {
var bbox = {};
bbox.x = x - r;
bbox.y = y - r;
bbox.width = bbox.height = r * 2;
return bbox
},
_getImageBbox: function(x, y) {
var bbox = {},
image = this._options.image,
width = image.width || DEFAULT_IMAGE_WIDTH,
height = image.height || DEFAULT_IMAGE_HEIGHT;
bbox.x = x - _round(width / 2);
bbox.y = y - _round(height / 2);
bbox.width = width;
bbox.height = height;
return bbox
},
_getGraphicBbox: function() {
var options = this._options,
x = this.x,
y = this.y,
bbox;
if (options.visible)
bbox = this._checkImage(options.image) ? this._getImageBbox(x, y) : this._getSymbolBbox(x, y, options.styles.normal.r);
else
bbox = {
x: x,
y: y,
width: 0,
height: 0
};
return bbox
},
_drawLabel: function(renderer, group) {
var that = this,
customVisibility = that._getCustomLabelVisibility(),
visibleArea,
translators = that.translators;
if ((that._options.series.getLabelVisibility() || customVisibility) && that.hasValue()) {
if (translators)
visibleArea = {
minX: translators.x.getCanvasVisibleArea().min,
maxX: translators.x.getCanvasVisibleArea().max,
minY: translators.y.getCanvasVisibleArea().min,
maxY: translators.y.getCanvasVisibleArea().max
};
that._label.setCoords({
x: that.x,
y: that.y
}, that._getGraphicBbox(), that._getLabelPosition(), visibleArea);
that._label.draw(renderer, group, customVisibility)
}
else
that._label.hide()
},
_drawMarker: function(renderer, group, animationEnabled) {
var that = this,
options = that._options,
translates = that._getTranslates(animationEnabled),
marker,
style = that._getStyle(),
pointAttributes = _extend({
translateX: translates.x,
translateY: translates.y
}, style),
pointSettings = {
attr: pointAttributes,
points: that._populatePointShape(options.symbol, style.r),
r: style.r
};
marker = that._createMarker(renderer, group, options.image, pointSettings, animationEnabled);
that.graphic = marker
},
_drawTrackerMarker: function(renderer, group) {
var radius = this._options.trackerR || this.storeTrackerR();
this.trackerGraphic = renderer.createCircle(this.x, this.y, radius).append(group);
this.trackerGraphic.data({point: this})
},
getTooltipCoords: function() {
var coords;
if (this.graphic)
coords = {
x: this.x,
y: this.y,
offset: this.graphic.getBBox().height / 2
};
else
coords = {
x: this.x,
y: this.y,
offset: 0
};
return coords
},
hasValue: function() {
return this.value !== null && this.minValue !== null
},
setPercentValue: function(total) {
var valuePercent = this.value / total || 0,
percent = valuePercent,
minValuePercent = this.minValue / total || 0;
percent -= _isNumber(this.minValue) ? minValuePercent : 0;
this._label.setDataField("percent", percent);
this._label.setDataField("total", total);
if (this._options.series.isFullStackedSeries() && this.hasValue()) {
this.value = valuePercent;
this.minValue = !minValuePercent ? this.minValue : minValuePercent;
this.translate()
}
},
storeTrackerR: function() {
var navigator = window.navigator,
r = this._options.styles.normal.r,
minTrackerSize;
navigator = this.__debug_navigator || navigator;
this.__debug_browserNavigator = navigator;
minTrackerSize = "ontouchstart" in window || navigator.msPointerEnabled && navigator.msMaxTouchPoints || navigator.pointerEnabled && navigator.maxTouchPoints ? 20 : 6;
this._options.trackerR = r < minTrackerSize ? minTrackerSize : r;
return this._options.trackerR
},
_translate: function(translators) {
var that = this,
mainAxis = that._options.rotated ? "x" : "y",
upperMainAxis = mainAxis.toUpperCase(),
mainTranslator = translators[mainAxis],
axis = that._options.rotated ? "y" : "x";
that[mainAxis] = mainTranslator.translate(that.value);
that[axis] = translators[axis].translate(that.argument);
that["min" + upperMainAxis] = mainTranslator.translate(that.minValue);
that["default" + upperMainAxis] = mainTranslator.translate(CANVAS_POSITION_DEFAULT);
that._calculateVisibility(that.x, that.y);
that._prepareStatesOptions()
},
_changeData: function(data) {
this.value = this.initialValue = this.originalValue = data.value;
this.argument = this.initialArgument = this.originalArgument = data.argument;
this.minValue = this.initialMinValue = this.originalMinValue = _isDefined(data.minValue) ? data.minValue : CANVAS_POSITION_DEFAULT;
this.tag = data.tag;
this.index = data.index
},
_updateData: function(data) {
if (this.argument !== data.argument || this.value !== data.value || this.tag !== data.tag)
this._changeData(data)
},
_getImageSettings: function(image) {
return {
href: image.url || image.toString(),
width: image.width || DEFAULT_IMAGE_WIDTH,
height: image.height || DEFAULT_IMAGE_HEIGHT
}
},
_updateMarker: function(animationEnabled, style) {
var that = this,
options = that._options,
style = style || this._getStyle(),
settings,
image = options.image;
if (that._checkImage(image))
settings = _extend({}, {visibility: style.visibility}, that._getImageSettings(image));
else
settings = _extend({}, style, {points: that._populatePointShape(options.symbol, style.r)});
if (!animationEnabled) {
settings.translateX = that.x;
settings.translateY = that.y
}
that.graphic.applySettings(settings)
},
_updateTracker: function() {
this.trackerGraphic.applySettings({
cx: this.x,
cy: this.y,
r: this.storeTrackerR()
})
},
_getLabelFormatObject: function() {
return {
argument: this.initialArgument,
value: this.initialValue,
originalArgument: this.originalArgument,
originalValue: this.originalValue,
seriesName: this._options.series.name,
point: this
}
},
_getLabelPosition: function() {
if (this._options.series.isFullStackedSeries() || this.initialValue > 0)
return "top";
else
return "bottom"
},
_getFormatObject: function(tooltip) {
var labelFormatObject = this._label.getData(),
valueObject = {
argumentText: tooltip.formatValue(this.initialArgument, "argument"),
valueText: tooltip.formatValue(this.initialValue)
},
percentObject = _isDefined(labelFormatObject.percent) ? {percentText: tooltip.formatValue(labelFormatObject.percent, "percent")} : {},
totalObject = _isDefined(labelFormatObject.total) ? {totalText: tooltip.formatValue(labelFormatObject.total)} : {};
return _extend({}, labelFormatObject, valueObject, percentObject, totalObject)
}
}
})(jQuery, DevExpress);
/*! Module viz-core, file barPoint.js */
(function($, DX) {
var viz = DevExpress.viz,
points = viz.core.series.points.mixins,
_extend = $.extend,
_math = Math,
_round = _math.round,
_abs = _math.abs,
_min = _math.min,
CANVAS_POSITION_DEFAULT = "canvas_position_default",
DEFAULT_BAR_TRACKER_SIZE = 9,
CORRECTING_BAR_TRACKER_VALUE = 4;
points.barPoint = _extend({}, points.symbolPoint, {
correctCoordinates: function(correctOptions) {
var correction = correctOptions.offset - _round(correctOptions.width / 2),
rotated = this._options.rotated,
valueSelector = rotated ? "height" : "width",
correctionSelector = (rotated ? "y" : "x") + "Correction";
this[valueSelector] = correctOptions.width;
this[correctionSelector] = correction
},
_getGraphicBbox: function() {
var bbox = {};
bbox.x = this.x;
bbox.y = this.y;
bbox.width = this.width;
bbox.height = this.height;
return bbox
},
_getLabelPosition: function() {
var position,
invertX = this.translators.x.getBusinessRange().invert,
invertY = this.translators.y.getBusinessRange().invert,
isDiscreteValue = this.series.valueAxisType === "discrete",
isFullStacked = this.series.isFullStackedSeries(),
notVerticalInverted = !isDiscreteValue && (this.initialValue >= 0 && !invertY || this.initialValue < 0 && invertY) || isDiscreteValue && !invertY || isFullStacked,
notHorizontalInverted = !isDiscreteValue && (this.initialValue >= 0 && !invertX || this.initialValue < 0 && invertX) || isDiscreteValue && !invertX || isFullStacked;
if (!this._options.rotated)
position = notVerticalInverted ? "top" : "bottom";
else
position = notHorizontalInverted ? "top" : "bottom";
return position
},
_drawLabel: function(renderer, group) {
var that = this,
options = that._options,
coords,
commonVisibility = options.series.getLabelVisibility(),
customVisibility = that._getCustomLabelVisibility(),
visibleArea,
translators = that.translators;
if (that.hasValue() && (options.label.showForZeroValues || that.initialValue) && (customVisibility || commonVisibility)) {
coords = {
x: that.x,
y: that.y,
defaultX: that.defaultX,
defaultY: that.defaultY
};
if (translators)
visibleArea = {
minX: translators.x.getCanvasVisibleArea().min,
maxX: translators.x.getCanvasVisibleArea().max,
minY: translators.y.getCanvasVisibleArea().min,
maxY: translators.y.getCanvasVisibleArea().max
};
that._label.setCoords(coords, that._getGraphicBbox(), that._getLabelPosition(), visibleArea);
that._label.draw(renderer, group, customVisibility)
}
else
that._label.hide()
},
_drawMarker: function(renderer, group, animationEnabled) {
var style = this._getStyle(),
x = this.x,
y = this.y,
width = this.width,
height = this.height;
if (animationEnabled)
if (this._options.rotated) {
width = 0;
x = this.defaultX
}
else {
height = 0;
y = this.defaultY
}
this.graphic = renderer.createRect(x, y, width, height, this._options.cornerRadius, style).append(group)
},
_getSettingsForTracker: function() {
var that = this,
y = that.y,
height = that.height,
x = that.x,
width = that.width;
if (that._options.rotated) {
if (width === 1) {
width = DEFAULT_BAR_TRACKER_SIZE;
x -= CORRECTING_BAR_TRACKER_VALUE
}
}
else if (height === 1) {
height = DEFAULT_BAR_TRACKER_SIZE;
y -= CORRECTING_BAR_TRACKER_VALUE
}
return {
x: x,
y: y,
width: width,
height: height
}
},
_drawTrackerMarker: function(renderer, group) {
var settings = this._getSettingsForTracker();
this.trackerGraphic = renderer.createRect(settings.x, settings.y, settings.width, settings.height, this._options.cornerRadius).append(group);
this.trackerGraphic.data({point: this})
},
getGraphicSettings: function() {
return {
x: this.graphic.settings.x || 0,
y: this.graphic.settings.y || 0,
height: this.graphic.settings.height || 0,
width: this.graphic.settings.width || 0
}
},
getTooltipCoords: function() {
var x = this.x + this.width / 2,
y = this.y + this.height / 2;
return {
x: x,
y: y,
offset: 0
}
},
_truncateCoord: function(coord, minBounce, maxBounce) {
if (coord < minBounce)
return minBounce;
if (coord > maxBounce)
return maxBounce;
return coord
},
_translate: function(translators) {
var that = this,
rotated = that._options.rotated,
valAxis = rotated ? "x" : "y",
argAxis = rotated ? "y" : "x",
valIntervalName = rotated ? "width" : "height",
argIntervalName = rotated ? "height" : "width",
argTranslator = translators[argAxis],
valTranslator = translators[valAxis],
argVisibleArea = argTranslator.getCanvasVisibleArea(),
valVisibleArea = valTranslator.getCanvasVisibleArea(),
arg,
minArg,
val,
minVal;
arg = minArg = argTranslator.translate(that.argument) + (that[argAxis + "Correction"] || 0);
val = valTranslator.translate(that.value);
minVal = valTranslator.translate(that.minValue);
that[valIntervalName] = _abs(val - minVal);
that._calculateVisibility(rotated ? _min(val, minVal) : _min(arg, minArg), rotated ? _min(arg, minArg) : _min(val, minVal), that.width, that.height);
val = that._truncateCoord(val, valVisibleArea.min, valVisibleArea.max);
minVal = that._truncateCoord(minVal, valVisibleArea.min, valVisibleArea.max);
that[argAxis] = arg;
that["min" + argAxis.toUpperCase()] = minArg;
that[valIntervalName] = _abs(val - minVal);
that[valAxis] = _min(val, minVal) + (that[valAxis + "Correction"] || 0);
that["min" + valAxis.toUpperCase()] = minVal + (that[valAxis + "Correction"] || 0);
that["default" + valAxis.toUpperCase()] = valTranslator.translate(CANVAS_POSITION_DEFAULT);
if (that.inVisibleArea) {
if (that[argAxis] < argVisibleArea.min) {
that[argIntervalName] = that[argIntervalName] - (argVisibleArea.min - that[argAxis]);
that[argAxis] = argVisibleArea.min;
that["min" + argAxis.toUpperCase()] = argVisibleArea.min
}
if (that[argAxis] + that[argIntervalName] > argVisibleArea.max)
that[argIntervalName] = argVisibleArea.max - that[argAxis]
}
},
_updateMarker: function(animationEnabled, style) {
var style = style || this._getStyle(),
attributes = _extend({}, style);
if (!animationEnabled) {
attributes.x = this.x;
attributes.y = this.y;
attributes.width = this.width;
attributes.height = this.height
}
else
attributes.sharpEdges = false;
this.graphic.applySettings(attributes)
},
_updateTracker: function() {
this.trackerGraphic.applySettings(this._getSettingsForTracker())
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file bubblePoint.js */
(function($, DX) {
var viz = DX.viz,
points = viz.core.series.points.mixins,
_extend = $.extend,
MIN_BUBBLE_HEIGHT = 20;
points.bubblePoint = _extend({}, points.symbolPoint, {
correctCoordinates: function(diameter) {
this.bubbleSize = diameter / 2
},
_drawMarker: function(renderer, group, animationEnabled) {
var style = this._getStyle(),
attr = _extend({
translateX: this.x,
translateY: this.y
}, style),
marker = renderer.createCircle(0, 0, animationEnabled ? 0 : this.bubbleSize, attr).append(group);
this.graphic = marker
},
_drawTrackerMarker: function(renderer, group) {
this.trackerGraphic = renderer.createCircle(this.x, this.y, this.bubbleSize).append(group);
this.trackerGraphic.data({point: this})
},
getTooltipCoords: function() {
if (this.graphic) {
var height = this.graphic.getBBox().height;
return {
x: this.x,
y: this.y,
offset: height < MIN_BUBBLE_HEIGHT ? height / 2 : 0
}
}
},
_getLabelFormatObject: function() {
var symbolMethods = points.symbolPoint,
formatObject = symbolMethods._getLabelFormatObject.call(this);
formatObject.size = this.initialSize;
return formatObject
},
_updateData: function(data) {
var symbolMethods = points.symbolPoint;
if (this.argument !== data.argument || this.value !== data.value || this.size !== data.size || this.tag !== data.tag) {
symbolMethods._changeData.call(this, data);
this.size = this.initialSize = data.size
}
},
_getGraphicBbox: function() {
return this._getSymbolBbox(this.x, this.y, this.bubbleSize)
},
_updateMarker: function(animationEnabled, style) {
var style = style || this._getStyle();
if (!animationEnabled)
style = $.extend({
r: this.bubbleSize,
translateX: this.x,
translateY: this.y
}, style);
this.graphic.applySettings(style)
},
_updateTracker: function() {
this.trackerGraphic.applySettings({
cx: this.x,
cy: this.y,
r: this.bubbleSize
})
},
_getFormatObject: function(tooltip) {
var symbolMethods = points.symbolPoint,
formatObject = symbolMethods._getFormatObject.call(this, tooltip);
formatObject.sizeText = tooltip.formatValue(this.initialSize);
return formatObject
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file piePoint.js */
(function($, DX) {
var viz = DevExpress.viz,
points = viz.core.series.points.mixins,
_extend = $.extend,
_round = Math.round,
_getCosAndSin = DX.utils.getCosAndSin;
points.piePoint = _extend({}, points.symbolPoint, {
_populatePointShape: function(target, deltaRadius) {
var angleFunctions = _getCosAndSin(point.middleAngle);
target.x = point.centerX - ~~(deltaRadius * angleFunctions.cos);
target.y = point.centerY + ~~(deltaRadius * angleFunctions.sin);
target.outerRadius = this.radiusOuter + deltaRadius;
target.innerRadius = this.radiusInner;
target.startAngle = this.toAngle;
target.endAngle = this.fromAngle
},
_changeData: function(data) {
var that = this;
that.value = that.initialValue = that.originalValue = data.value;
that.argument = that.initialArgument = that.originalArgument = data.argument;
that.minValue = that.initialMinValue = that.originalMinValue = DevExpress.utils.isDefined(data.minValue) ? data.minValue : 0;
that.tag = data.tag;
that._visible = true;
that.index = data.index
},
animate: function(complete, duration, step) {
this.graphic.animate({
x: this.centerX,
y: this.centerY,
outerRadius: this.radiusOuter,
innerRadius: this.radiusInner,
startAngle: this.toAngle,
endAngle: this.fromAngle
}, {
partitionDuration: duration,
step: step
}, complete)
},
correctPosition: function(correction) {
this.radiusInner = correction.radiusInner;
this.radiusOuter = correction.radiusOuter;
this.centerX = correction.centerX;
this.centerY = correction.centerY
},
correctValue: function(correction, percent, base) {
this.value = (base || this.initialValue) + correction;
this.minValue = correction;
this.percent = percent;
this._label.setDataField("percent", percent)
},
_getLabelOptions: function() {
var options = this._options,
series = options.series,
seriesStyle = this._options.styles.normal,
borderWidth = series._options.containerBackgroundColor === seriesStyle.stroke ? _round(seriesStyle.strokeWidth / 2) : _round(-seriesStyle.strokeWidth / 2);
return {
options: options.label,
borderWidth: borderWidth
}
},
_updateLabelData: function() {
this._label.updateData({formatObject: this._getLabelFormatObject()})
},
_updateLabelOptions: function() {
!this._label && this._createLabel();
this._label.setOptions(this._getLabelOptions())
},
_drawLabel: function(renderer, group) {
var commonVisibility = this._options.series.getLabelVisibility(),
customVisibility = this._getCustomLabelVisibility();
if ((commonVisibility || customVisibility) && this.hasValue()) {
this._label.setCoords({
middleAngle: this.middleAngle,
radiusOuter: this.radiusOuter,
centerX: this.centerX,
centerY: this.centerY
}, this._options.series.canvas);
this._label.draw(renderer, group, customVisibility)
}
else
this._label.hide()
},
_drawMarker: function(renderer, group, animationEnabled, firstDrawing) {
var styles = this._getStyle(),
radiusOuter = this.radiusOuter,
radiusInner = this.radiusInner,
fromAngle = this.fromAngle,
toAngle = this.toAngle;
if (animationEnabled) {
radiusInner = radiusOuter = 0;
if (!firstDrawing)
fromAngle = toAngle = this.shiftedAngle
}
this.graphic = renderer.createArc(this.centerX, this.centerY, radiusOuter, radiusInner, toAngle, fromAngle, styles).append(group)
},
_drawTrackerMarker: function(renderer, group) {
this.trackerGraphic = renderer.createArc(this.centerX, this.centerY, this.radiusOuter, this.radiusInner, this.toAngle, this.fromAngle).append(group);
this.trackerGraphic.data({point: this})
},
getTooltipCoords: function() {
var angleFunctions = _getCosAndSin(this.middleAngle);
return {
x: this.centerX + (this.radiusInner + (this.radiusOuter - this.radiusInner) / 2) * angleFunctions.cos,
y: this.centerY - (this.radiusInner + (this.radiusOuter - this.radiusInner) / 2) * angleFunctions.sin,
offset: 0
}
},
_translate: function(translator) {
var angle = this.shiftedAngle || 0;
this.fromAngle = translator.translate(this.minValue) + angle;
this.toAngle = translator.translate(this.value) + angle;
this.middleAngle = translator.translate((this.value - this.minValue) / 2 + this.minValue) + angle;
if (!this.isVisible())
this.middleAngle = this.toAngle = this.fromAngle = this.fromAngle || angle
},
_updateMarker: function(animationEnabled, style) {
style = style || this._getStyle();
if (!animationEnabled)
style = _extend({
x: this.centerX,
y: this.centerY,
outerRadius: this.radiusOuter,
innerRadius: this.radiusInner,
startAngle: this.toAngle,
endAngle: this.fromAngle
}, style);
this.graphic.applySettings(style)
},
_updateTracker: function() {
this.trackerGraphic.applySettings({
x: this.centerX,
y: this.centerY,
outerRadius: this.radiusOuter,
innerRadius: this.radiusInner,
startAngle: this.toAngle,
endAngle: this.fromAngle
})
},
getLegendStyles: function() {
return this._styles.legendStyles
},
isInVisibleArea: function() {
return true
},
hide: function() {
if (this._visible) {
this._visible = false;
this.hideTooltip();
this._options.visibilityChanged(this)
}
},
show: function() {
if (!this._visible) {
this._visible = true;
this._options.visibilityChanged(this)
}
},
setInvisibility: function() {
this._setTrackerInvisibility();
this._label.hide()
},
isVisible: function() {
return this._visible
},
_getFormatObject: function(tooltip) {
var symbolMethods = points.symbolPoint,
formatObject = symbolMethods._getFormatObject.call(this, tooltip);
formatObject.percent = this.percent;
formatObject.percentText = tooltip.formatValue(this.percent, "percent");
return formatObject
},
getColor: function() {
return this._styles.normal.fill
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file rangeSymbolPoint.js */
(function($, DX) {
var viz = DevExpress.viz,
points = viz.core.series.points.mixins,
_extend = $.extend,
_isDefined = DX.utils.isDefined,
_math = Math,
_abs = _math.abs,
_min = _math.min,
_max = _math.max,
_round = _math.round,
DEFAULT_IMAGE_WIDTH = 20,
DEFAULT_IMAGE_HEIGHT = 20;
points.rangeSymbolPoint = _extend({}, points.symbolPoint, {
deleteLabel: function() {
this._topLabel.dispose();
this._topLabel = null;
this._bottomLabel.dispose();
this._bottomLabel = null
},
hideMarker: function(type) {
var marker = this.graphic && this.graphic[type + "Marker"],
label = this["_" + type + "Label"];
if (marker && marker.settings.visibility !== "hidden")
marker.applySettings({visibility: "hidden"});
label.hide()
},
setInvisibility: function() {
this.hideMarker("top");
this.hideMarker("bottom");
this._setTrackerInvisibility()
},
clearVisibility: function() {
var graphic = this.graphic;
if (graphic) {
if (graphic.topMarker && graphic.topMarker.settings.visibility)
graphic.topMarker.applySettings({visibility: null});
if (graphic.bottomMarker && graphic.bottomMarker.settings.visibility)
graphic.bottomMarker.applySettings({visibility: null})
}
this._clearTrackerVisibility();
this._topLabel.clearVisibility();
this._bottomLabel.clearVisibility()
},
clearMarker: function() {
if (this.graphic) {
this.graphic.topMarker && this.graphic.topMarker.applySettings(this._emptySettings);
this.graphic.bottomMarker && this.graphic.bottomMarker.applySettings(this._emptySettings)
}
},
_getLabelPosition: function(markerType) {
var position,
rotated = this._options.rotated,
invertY = this.translators.y.getBusinessRange().invert,
invertX = this.translators.x.getBusinessRange().invert,
isDiscreteValue = this._options.series._options.valueAxisType === "discrete",
notInverted = isDiscreteValue && (!invertY && !rotated || invertX && rotated) || !isDiscreteValue && this.value > this.minValue && (!invertY && !rotated || !invertX && rotated);
if (markerType === "top")
position = notInverted ? "top" : "bottom";
else
position = notInverted ? "bottom" : "top";
return position
},
_getLabelMinFormatObject: function() {
return {
index: 0,
argument: this.initialArgument,
value: this.initialMinValue,
seriesName: this._options.series.name,
originalValue: this.originalMinValue,
originalArgument: this.originalArgument,
point: this
}
},
_updateLabelData: function() {
var maxFormatObject = this._getLabelFormatObject();
maxFormatObject.index = 1;
this._topLabel.updateData({
formatObject: maxFormatObject,
initialValue: this.initialValue
});
this._bottomLabel.updateData({
formatObject: this._getLabelMinFormatObject(),
initialValue: this.initialMinValue
})
},
_updateLabelOptions: function(type) {
var options = this._getLabelOptions(type);
(!this._topLabel || !this._bottomLabel) && this._createLabel();
this._topLabel.setOptions(options);
this._bottomLabel.setOptions(options)
},
setAdjustSeriesLabels: function(adjustSeriesLabels) {
this._topLabel.adjustSeriesLabels = adjustSeriesLabels;
this._bottomLabel.adjustSeriesLabels = adjustSeriesLabels
},
_createLabel: function() {
this._topLabel = viz.core.CoreFactory.createLabel();
this._bottomLabel = viz.core.CoreFactory.createLabel()
},
_getLabelCoords: function(location) {
var coords = {},
isTop = location === "top";
if (!this._options.rotated) {
coords.x = this.x;
coords.y = isTop ? _min(this.y, this.minY) : _max(this.y, this.minY)
}
else {
coords.x = isTop ? _max(this.x, this.minX) : _min(this.x, this.minX);
coords.y = this.y
}
return coords
},
_getGraphicBbox: function(location) {
var options = this._options,
rotated = options.rotated,
isTop = location === "top",
images = this._getImage(options.image),
image = isTop ? this._checkImage(images.top) : this._checkImage(images.bottom),
bbox,
x,
y;
if (!rotated) {
x = this.x;
y = isTop ? _min(this.y, this.minY) : _max(this.y, this.minY)
}
else {
x = isTop ? _max(this.x, this.minX) : _min(this.x, this.minX);
y = this.y
}
if (options.visible)
bbox = image ? this._getImageBbox(x, y) : this._getSymbolBbox(x, y, options.styles.normal.r);
else
bbox = {
x: x,
y: y,
width: 0,
height: 0
};
return bbox
},
_checkOverlay: function(bottomCoord, topCoord, topValue) {
return bottomCoord < topCoord + topValue
},
_getOverlayCorrections: function(type, topCoords, bottomCoords) {
var isVertical = type === "vertical",
coordSelector = isVertical ? "y" : "x",
valueSelector = isVertical ? "height" : "width",
visibleArea = this.translators[coordSelector].getCanvasVisibleArea(),
minBound = visibleArea.min,
maxBound = visibleArea.max,
delta = _round((topCoords[coordSelector] + topCoords[valueSelector] - bottomCoords[coordSelector]) / 2),
coord1 = topCoords[coordSelector] - delta,
coord2 = bottomCoords[coordSelector] + delta;
if (coord1 < minBound) {
delta = minBound - topCoords[coordSelector];
coord1 += delta;
coord2 += delta
}
else if (coord2 + bottomCoords[valueSelector] > maxBound) {
delta = -(bottomCoords[coordSelector] + bottomCoords[valueSelector] - maxBound);
coord1 += delta;
coord2 += delta
}
return {
coord1: coord1,
coord2: coord2
}
},
_checkLabelsOverlay: function(topLocation) {
var that = this,
topCoords = that._topLabel.getCoords(),
bottomCoords = that._bottomLabel.getCoords(),
corrections = {};
if (!that._options.rotated) {
if (topLocation === "top") {
if (this._checkOverlay(bottomCoords.y, topCoords.y, topCoords.height)) {
corrections = this._getOverlayCorrections("vertical", topCoords, bottomCoords);
that._topLabel.updatePosition(undefined, corrections.coord1);
that._bottomLabel.updatePosition(undefined, corrections.coord2)
}
}
else if (this._checkOverlay(topCoords.y, bottomCoords.y, bottomCoords.height)) {
corrections = this._getOverlayCorrections("vertical", bottomCoords, topCoords);
that._topLabel.updatePosition(undefined, corrections.coord2);
that._bottomLabel.updatePosition(undefined, corrections.coord1)
}
}
else if (topLocation === "top") {
if (this._checkOverlay(topCoords.x, bottomCoords.x, bottomCoords.width)) {
corrections = this._getOverlayCorrections("horizontal", bottomCoords, topCoords);
that._topLabel.updatePosition(corrections.coord2);
that._bottomLabel.updatePosition(corrections.coord1)
}
}
else if (this._checkOverlay(bottomCoords.x, topCoords.x, topCoords.width)) {
corrections = this._getOverlayCorrections("horizontal", topCoords, bottomCoords);
that._topLabel.updatePosition(corrections.coord1);
that._bottomLabel.updatePosition(corrections.coord2)
}
},
_drawLabel: function(renderer, group) {
var topCoords,
bottomCoords,
rotated = this._options.rotated,
topLocation = this._getLabelPosition("top"),
bottomLocation = this._getLabelPosition("bottom"),
isInside = this._options.label.position === "inside",
topPosition = isInside ? bottomLocation : topLocation,
bottomPosition = isInside ? topLocation : bottomLocation,
translators = this.translators,
visibleArea,
customVisibility = this._getCustomLabelVisibility(),
commonVisibility = this._options.series.getLabelVisibility();
if ((commonVisibility || customVisibility) && this.hasValue()) {
if (translators)
visibleArea = {
minX: translators.x.getCanvasVisibleArea().min,
maxX: translators.x.getCanvasVisibleArea().max,
minY: translators.y.getCanvasVisibleArea().min,
maxY: translators.y.getCanvasVisibleArea().max
};
this._topLabel.setCoords(this._getLabelCoords(topLocation), this._getGraphicBbox(topLocation), topPosition, visibleArea);
this._bottomLabel.setCoords(this._getLabelCoords(bottomLocation), this._getGraphicBbox(bottomLocation), bottomPosition, visibleArea);
this.visibleTopMarker && this._topLabel.draw(renderer, group, customVisibility);
this.visibleBottomMarker && this._bottomLabel.draw(renderer, group, customVisibility);
this._checkLabelsOverlay(topLocation)
}
else {
this._topLabel.hide();
this._bottomLabel.hide()
}
},
_getImage: function(imageOption) {
var image = {};
if (_isDefined(imageOption))
if (typeof imageOption === "string")
image.top = image.bottom = imageOption;
else {
image.top = {
url: typeof imageOption.url === "string" ? imageOption.url : imageOption.url && imageOption.url.rangeMaxPoint,
width: typeof imageOption.width === "number" ? imageOption.width : imageOption.width && imageOption.width.rangeMaxPoint,
height: typeof imageOption.height === "number" ? imageOption.height : imageOption.height && imageOption.height.rangeMaxPoint
};
image.bottom = {
url: typeof imageOption.url === "string" ? imageOption.url : imageOption.url && imageOption.url.rangeMinPoint,
width: typeof imageOption.width === "number" ? imageOption.width : imageOption.width && imageOption.width.rangeMinPoint,
height: typeof imageOption.height === "number" ? imageOption.height : imageOption.height && imageOption.height.rangeMinPoint
}
}
return image
},
_checkSymbol: function(oldOptions, newOptions) {
var oldSymbol = oldOptions.symbol,
newSymbol = newOptions.symbol,
symbolChanged = oldSymbol === "circle" && newSymbol !== "circle" || oldSymbol !== "circle" && newSymbol === "circle",
oldImages = this._getImage(oldOptions.image),
newImages = this._getImage(newOptions.image),
topImageChanged = this._checkImage(oldImages.top) !== this._checkImage(newImages.top),
bottomImageChanged = this._checkImage(oldImages.bottom) !== this._checkImage(newImages.bottom);
return symbolChanged || topImageChanged || bottomImageChanged
},
_getSettingsForTwoMarkers: function(style) {
var that = this,
options = that._options,
settings = {},
x = options.rotated ? _min(that.x, that.minX) : that.x,
y = options.rotated ? that.y : _min(that.y, that.minY),
radius = style.r,
points = that._populatePointShape(options.symbol, radius);
settings.top = {
r: radius,
points: points,
attr: _extend({
translateX: x + that.width,
translateY: y
}, style)
};
settings.bottom = {
r: radius,
points: points,
attr: _extend({
translateX: x,
translateY: y + that.height
}, style)
};
return settings
},
_hasGraphic: function() {
return this.graphic && this.graphic.topMarker && this.graphic.bottomMarker
},
_drawOneMarker: function(renderer, markerType, imageSettings, settings) {
if (this.graphic[markerType])
this._updateOneMarker(markerType, settings);
else
this.graphic[markerType] = this._createMarker(renderer, this.graphic, imageSettings, settings)
},
_drawMarker: function(renderer, group, animationEnabled, style) {
var that = this,
style = style || that._getStyle(),
settings = that._getSettingsForTwoMarkers(style),
image = that._getImage(that._options.image);
if (that._checkImage(image.top))
settings.top = that._getImageSettings(settings.top, image.top);
if (that._checkImage(image.bottom))
settings.bottom = that._getImageSettings(settings.bottom, image.bottom);
that.graphic = that.graphic || renderer.createGroup().append(group);
that.visibleTopMarker && that._drawOneMarker(renderer, 'topMarker', image.top, settings.top);
that.visibleBottomMarker && that._drawOneMarker(renderer, 'bottomMarker', image.bottom, settings.bottom)
},
_getSettingsForTracker: function(radius) {
var that = this,
options = that._options,
x = options.rotated ? _min(that.x, that.minX) - radius : that.x - radius,
y = options.rotated ? that.y - radius : _min(that.y, that.minY) - radius,
width = that.width + 2 * radius,
height = that.height + 2 * radius;
return {
translateX: x,
translateY: y,
width: width,
height: height
}
},
_drawTrackerMarker: function(renderer, group) {
var that = this,
options = that._options,
radius = options.trackerR || that.storeTrackerR(),
settings = that._getSettingsForTracker(radius),
attr = {
translateX: settings.translateX,
translateY: settings.translateY
};
that.trackerGraphic = renderer.createRect(0, 0, settings.width, settings.height, 0, attr).append(group);
that.trackerGraphic.data({point: that})
},
isInVisibleArea: function() {
var that = this,
minArgument = _min(that.minX, that.x) || that.x,
maxArgument = _max(that.minX, that.x) || that.x,
maxValue = _max(that.minY, that.y) || that.y,
minValue = _min(that.minY, that.y) || that.y,
notVisibleBothMarkersRight,
notVisibleBothMarkersLeft,
notVisibleBothMarkersBottom,
notVisibleBothMarkersTop,
visibleTopMarker = true,
visibleBottomMarker = true,
visibleRangeArea = true,
visibleAreaX,
visibleAreaY;
if (that.translators) {
visibleAreaX = that.translators.x.getCanvasVisibleArea();
visibleAreaY = that.translators.y.getCanvasVisibleArea();
notVisibleBothMarkersRight = visibleAreaX.max < minArgument && visibleAreaX.max < maxArgument;
notVisibleBothMarkersLeft = visibleAreaX.min > minArgument && visibleAreaX.min > maxArgument;
notVisibleBothMarkersTop = visibleAreaY.min > minValue && visibleAreaY.min > maxValue;
notVisibleBothMarkersBottom = visibleAreaY.max < minValue && visibleAreaY.max < maxValue;
if (notVisibleBothMarkersTop || notVisibleBothMarkersBottom || notVisibleBothMarkersRight || notVisibleBothMarkersLeft)
visibleTopMarker = visibleBottomMarker = visibleRangeArea = false;
else if (!that._options.rotated) {
visibleTopMarker = visibleAreaY.min < minValue && visibleAreaY.max > minValue;
visibleBottomMarker = visibleAreaY.min < maxValue && visibleAreaY.max > maxValue
}
else {
visibleBottomMarker = visibleAreaX.min < minArgument && visibleAreaX.max > minArgument;
visibleTopMarker = visibleAreaX.min < maxArgument && visibleAreaX.max > maxArgument
}
}
that.visibleTopMarker = visibleTopMarker;
that.visibleBottomMarker = visibleBottomMarker;
that.visibleRangeArea = visibleRangeArea;
return visibleRangeArea
},
getTooltipCoords: function() {
var that = this,
x,
y,
min,
max,
minValue,
visibleAreaX = that.translators.x.getCanvasVisibleArea(),
visibleAreaY = that.translators.y.getCanvasVisibleArea();
if (!that._options.rotated) {
minValue = _min(that.y, that.minY);
x = that.x;
min = visibleAreaY.min > minValue ? visibleAreaY.min : minValue;
max = visibleAreaY.max < minValue + that.height ? visibleAreaY.max : minValue + that.height;
y = min + (max - min) / 2
}
else {
minValue = _min(that.x, that.minX);
y = that.y;
min = visibleAreaX.min > minValue ? visibleAreaX.min : minValue;
max = visibleAreaX.max < minValue + that.width ? visibleAreaX.max : minValue + that.width;
x = min + (max - min) / 2
}
return {
x: x,
y: y,
offset: 0
}
},
_translate: function(translators) {
var symbolMethods = points.symbolPoint;
this.minX = this.minY = translators.y.translate(this.minValue);
symbolMethods._translate.call(this, translators);
this.height = this._options.rotated ? 0 : _abs(this.minY - this.y);
this.width = this._options.rotated ? _abs(this.x - this.minX) : 0
},
_updateData: function(data) {
if (this.argument !== data.argument || this.value !== data.value || this.minValue !== data.minValue || this.tag !== data.tag) {
this._changeData(data);
this.minValue = this.initialMinValue = this.originalMinValue = data.minValue
}
},
_getImageSettings: function(settings, image) {
var x = settings.attr.translateX,
y = settings.attr.translateY;
return {
href: image.url || image.toString(),
width: image.width || DEFAULT_IMAGE_WIDTH,
height: image.height || DEFAULT_IMAGE_HEIGHT,
attr: {
translateX: x,
translateY: y
}
}
},
_updateOneMarker: function(markerType, settings) {
this.graphic && this.graphic[markerType] && this.graphic[markerType].applySettings(_extend({}, settings, settings.attr))
},
_updateMarker: function(animationEnabled, style) {
this._drawMarker(undefined, undefined, undefined, style)
},
_updateTracker: function() {
var radius = this.storeTrackerR(),
settings = this._getSettingsForTracker(radius);
this.trackerGraphic.applySettings(settings)
},
_getFormatObject: function(tooltip) {
var minValue = tooltip.formatValue(this.initialMinValue),
value = tooltip.formatValue(this.initialValue);
return {
argument: this.initialArgument,
argumentText: tooltip.formatValue(this.initialArgument, "argument"),
valueText: minValue + " - " + value,
rangeValue1Text: minValue,
rangeValue2Text: value,
rangeValue1: this.initialMinValue,
rangeValue2: this.initialValue,
seriesName: this.series.name,
point: this,
originalMinValue: this.originalMinValue,
originalValue: this.originalValue,
originalArgument: this.originalArgument
}
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file rangeBarPoint.js */
(function($, DX) {
var viz = DevExpress.viz,
points = viz.core.series.points.mixins,
_isDefined = DX.utils.isDefined,
rangeSymbolPointMethods = points.rangeSymbolPoint,
_extend = $.extend;
points.rangeBarPoint = _extend({}, points.barPoint, {
deleteLabel: rangeSymbolPointMethods.deleteLabel,
_getFormatObject: rangeSymbolPointMethods._getFormatObject,
setAdjustSeriesLabels: rangeSymbolPointMethods.setAdjustSeriesLabels,
clearVisibility: function() {
if (this.graphic && this.graphic.settings.visibility)
this.graphic.applySettings({visibility: null});
this._topLabel.clearVisibility();
this._bottomLabel.clearVisibility()
},
setInvisibility: function() {
if (this.graphic && this.graphic.settings.visibility !== "hidden")
this.graphic.applySettings({visibility: "hidden"});
this._topLabel.hide();
this._bottomLabel.hide()
},
_translate: function(translator) {
var barMethods = points.barPoint;
barMethods._translate.call(this, translator);
if (this._options.rotated)
this.width = this.width || 1;
else
this.height = this.height || 1
},
_updateData: rangeSymbolPointMethods._updateData,
_getLabelPosition: rangeSymbolPointMethods._getLabelPosition,
_getLabelMinFormatObject: rangeSymbolPointMethods._getLabelMinFormatObject,
_updateLabelData: rangeSymbolPointMethods._updateLabelData,
_updateLabelOptions: rangeSymbolPointMethods._updateLabelOptions,
_createLabel: rangeSymbolPointMethods._createLabel,
_checkOverlay: rangeSymbolPointMethods._checkOverlay,
_getOverlayCorrections: rangeSymbolPointMethods._getOverlayCorrections,
_drawLabel: function(renderer, group) {
var topCoords,
bottomCoords,
rotated = this._options.rotated,
topLocation = this._getLabelPosition("top"),
bottomLocation = this._getLabelPosition("bottom"),
bbox = this._getGraphicBbox(),
coords = {
x: this.x,
y: this.y,
defaultX: this.defaultX,
defaultY: this.defaultY
},
translators = this.translators,
visibleArea,
customVisibility = this._getCustomLabelVisibility(),
commonVisibility = this._options.series.getLabelVisibility();
if ((customVisibility || commonVisibility) && this.hasValue()) {
if (translators)
visibleArea = {
minX: translators.x.getCanvasVisibleArea().min,
maxX: translators.x.getCanvasVisibleArea().max,
minY: translators.y.getCanvasVisibleArea().min,
maxY: translators.y.getCanvasVisibleArea().max
};
this._topLabel.setCoords(coords, bbox, topLocation, visibleArea);
this._bottomLabel.setCoords(coords, bbox, bottomLocation, visibleArea);
this._topLabel.draw(renderer, group, customVisibility);
this._bottomLabel.draw(renderer, group, customVisibility);
rangeSymbolPointMethods._checkLabelsOverlay.call(this, topLocation)
}
else {
this._topLabel.hide();
this._bottomLabel.hide()
}
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file candlestickPoint.js */
(function($, DX) {
var viz = DevExpress.viz,
points = viz.core.series.points.mixins,
_isNumeric = $.isNumeric,
_extend = $.extend,
_math = Math,
_abs = _math.abs,
_min = _math.min,
_max = _math.max,
_round = _math.round,
DEFAULT_FINANCIAL_TRACKER_MARGIN = 2;
points.candlestickPoint = _extend({}, points.barPoint, {
_getContinuousPoints: function(minValueName, maxValueName) {
var that = this,
x = that.x,
createPoint = that._options.rotated ? function(x, y) {
return {
x: y,
y: x
}
} : function(x, y) {
return {
x: x,
y: y
}
},
width = that.width,
min = that[minValueName],
max = that[maxValueName],
points;
if (min === max)
points = [createPoint(x, that.highY), createPoint(x, that.lowY), createPoint(x, that.closeY), createPoint(x - width / 2, that.closeY), createPoint(x + width / 2, that.closeY), createPoint(x, that.closeY)];
else
points = [createPoint(x, that.highY), createPoint(x, max), createPoint(x + width / 2, max), createPoint(x + width / 2, min), createPoint(x, min), createPoint(x, that.lowY), createPoint(x, min), createPoint(x - width / 2, min), createPoint(x - width / 2, max), createPoint(x, max)];
return points
},
_getCategoryPoints: function(y) {
var that = this,
x = that.x,
createPoint = that._options.rotated ? function(x, y) {
return {
x: y,
y: x
}
} : function(x, y) {
return {
x: x,
y: y
}
};
return [createPoint(x, that.highY), createPoint(x, that.lowY), createPoint(x, y), createPoint(x - that.width / 2, y), createPoint(x + that.width / 2, y), createPoint(x, y)]
},
_getPoints: function() {
var that = this,
points,
minValueName,
maxValueName,
openValue = that.openValue,
closeValue = that.closeValue;
if (_isNumeric(openValue) && _isNumeric(closeValue)) {
minValueName = openValue > closeValue ? "closeY" : "openY";
maxValueName = openValue > closeValue ? "openY" : "closeY";
points = that._getContinuousPoints(minValueName, maxValueName)
}
else if (openValue === closeValue)
points = [{
x: that.x,
y: that.highY
}, {
x: that.x,
y: that.lowY
}];
else
points = that._getCategoryPoints(_isNumeric(openValue) ? that.openY : that.closeY);
return points
},
getColor: function() {
return this._isReduction ? this._options.reduction.color : this._styles.normal.stroke || this.series.getColor()
},
_drawMarkerInGroup: function(group, attributes, renderer) {
this.graphic = renderer.createArea(this._getPoints(), attributes).append(group)
},
_fillStyle: function() {
var styles = this._options.styles;
if (this._isReduction && this._isPositive)
this._styles = styles.reductionPositive;
else if (this._isReduction)
this._styles = styles.reduction;
else if (this._isPositive)
this._styles = styles.positive;
else
this._styles = styles
},
_getMinTrackerWidth: function() {
return 1 + 2 * this._styles.normal.strokeWidth
},
correctCoordinates: function(correctOptions) {
var minWidth = this._getMinTrackerWidth(),
maxWidth = 10;
this.width = correctOptions.width < minWidth ? minWidth : correctOptions.width > maxWidth ? maxWidth : correctOptions.width;
this.xCorrection = correctOptions.offset
},
_getMarkerGroup: function(group) {
var markerGroup;
if (this._isReduction && this._isPositive)
markerGroup = group.reductionPositiveMarkersGroup;
else if (this._isReduction)
markerGroup = group.reductionMarkersGroup;
else if (this._isPositive)
markerGroup = group.defaultPositiveMarkersGroup;
else
markerGroup = group.defaultMarkersGroup;
return markerGroup
},
_drawMarker: function(renderer, group) {
var attributes = this._getStyle(),
rotated = this._options.rotated,
pointGroup = this._getMarkerGroup(group);
this._drawMarkerInGroup(pointGroup, attributes, renderer)
},
_getSettingsForTracker: function() {
var that = this,
highY = that.highY,
lowY = that.lowY,
rotated = that._options.rotated,
x,
y,
width,
height;
if (highY === lowY) {
highY = rotated ? highY + DEFAULT_FINANCIAL_TRACKER_MARGIN : highY - DEFAULT_FINANCIAL_TRACKER_MARGIN;
lowY = rotated ? lowY - DEFAULT_FINANCIAL_TRACKER_MARGIN : lowY + DEFAULT_FINANCIAL_TRACKER_MARGIN
}
if (rotated) {
x = _min(lowY, highY);
y = that.x - that.width / 2;
width = _abs(lowY - highY);
height = that.width
}
else {
x = that.x - that.width / 2;
y = _min(lowY, highY);
width = that.width;
height = _abs(lowY - highY)
}
return {
x: x,
y: y,
width: width,
height: height
}
},
_drawTrackerMarker: function(renderer, group) {
var settings = this._getSettingsForTracker();
this.trackerGraphic = renderer.createRect(settings.x, settings.y, settings.width, settings.height, 0).append(group);
this.trackerGraphic.data({point: this})
},
_getGraphicBbox: function() {
var bbox = {},
rotated = this._options.rotated;
bbox.x = !rotated ? this.x - _round(this.width / 2) : this.lowY;
bbox.y = !rotated ? this.highY : this.x - _round(this.width / 2);
bbox.width = !rotated ? this.width : this.highY - this.lowY;
bbox.height = !rotated ? this.lowY - this.highY : this.width;
return bbox
},
_drawLabel: function(renderer, group) {
var coords,
commonVisibility = this._options.series.getLabelVisibility(),
customVisibility = this._getCustomLabelVisibility(),
visibleArea,
reductionColor = this._options.reduction.color,
translators = this.translators;
if (this.hasValue() && (commonVisibility || customVisibility)) {
visibleArea = {
minX: translators.x.getCanvasVisibleArea().min,
maxX: translators.x.getCanvasVisibleArea().max,
minY: translators.y.getCanvasVisibleArea().min,
maxY: translators.y.getCanvasVisibleArea().max
};
if (this._isReduction)
this._label.updateOptions({options: {
background: {fill: reductionColor},
connector: {stroke: reductionColor}
}});
coords = this._options.rotated ? {
x: this.highY,
y: this.x
} : {
x: this.x,
y: this.highY
};
this._label.setCoords(coords, this._getGraphicBbox(), "top", visibleArea);
this._label.draw(renderer, group, customVisibility)
}
},
getTooltipCoords: function() {
var that = this;
if (that.graphic) {
var x,
y,
min,
max,
minValue = _min(that.lowY, that.highY),
maxValue = _max(that.lowY, that.highY),
visibleAreaX = that.translators.x.getCanvasVisibleArea(),
visibleAreaY = that.translators.y.getCanvasVisibleArea();
if (!that._options.rotated) {
min = _max(visibleAreaY.min, minValue);
max = _min(visibleAreaY.max, maxValue);
x = that.x;
y = min + (max - min) / 2
}
else {
min = _max(visibleAreaX.min, minValue);
max = _min(visibleAreaX.max, maxValue);
y = that.x;
x = min + (max - min) / 2
}
return {
x: x,
y: y,
offset: 0
}
}
},
hasValue: function() {
return this.highValue !== null && this.lowValue !== null
},
_translate: function(translator) {
var that = this,
rotated = that._options.rotated,
argTranslator = rotated ? that.translators.y : that.translators.x,
valTranslator = rotated ? that.translators.x : that.translators.y,
centerValue,
height;
that.x = argTranslator.translate(that.argument) + (that.xCorrection || 0);
that.openY = that.openValue !== null ? valTranslator.translate(that.openValue) : null;
that.highY = valTranslator.translate(that.highValue);
that.lowY = valTranslator.translate(that.lowValue);
that.closeY = that.closeValue !== null ? valTranslator.translate(that.closeValue) : null;
height = _abs(that.lowY - that.highY);
centerValue = _min(that.lowY, that.highY) + _abs(that.lowY - that.highY) / 2;
that._calculateVisibility(!rotated ? that.x : centerValue, !rotated ? centerValue : that.x)
},
_updateData: function(data) {
var that = this;
if (that.argument !== data.argument || that.reductionValue !== data.reductionValue || that.highValue !== data.highValue || that.lowValue !== data.lowValue || that.openValue !== data.openValue || that.closeValue !== data.closeValue || that.tag !== data.tag) {
that.value = that.initialValue = data.reductionValue;
that.originalValue = data.value;
that.argument = that.initialArgument = data.argument;
that.originalArgument = data.argument;
that.lowValue = data.lowValue;
that.originalLowValue = data.lowValue;
that.highValue = data.highValue;
that.originalHighValue = data.highValue;
that.openValue = data.openValue;
that.originalOpenValue = data.openValue;
that.closeValue = data.closeValue;
that.originalCloseValue = data.closeValue;
that.tag = data.tag;
that.pointClassName = data.pointClassName;
that._isPositive = data.openValue < data.closeValue;
that._isReduction = data.isReduction
}
},
_updateMarker: function(animationEnabled, style, group) {
var style = style || this._getStyle();
this.graphic.applySettings(_extend({points: this._getPoints()}, style));
group && this.graphic.append(this._getMarkerGroup(group))
},
_updateTracker: function() {
this.trackerGraphic.applySettings(this._getSettingsForTracker())
},
_getLabelFormatObject: function() {
return {
openValue: this.openValue,
highValue: this.highValue,
lowValue: this.lowValue,
closeValue: this.closeValue,
reductionValue: this.initialValue,
argument: this.initialArgument,
value: this.initialValue,
seriesName: this._options.series.name,
originalOpenValue: this.originalOpenValue,
originalCloseValue: this.originalCloseValue,
originalLowValue: this.originalLowValue,
originalHighValue: this.originalHighValue,
originalArgument: this.originalArgument,
point: this
}
},
_getFormatObject: function(tooltip) {
var highValue = tooltip.formatValue(this.highValue),
openValue = tooltip.formatValue(this.openValue),
closeValue = tooltip.formatValue(this.closeValue),
lowValue = tooltip.formatValue(this.lowValue),
symbolMethods = points.symbolPoint,
formatObject = symbolMethods._getFormatObject.call(this, tooltip);
return _extend({}, formatObject, {
valueText: "h: " + highValue + (openValue !== "" ? " o: " + openValue : "") + (closeValue !== "" ? " c: " + closeValue : "") + " l: " + lowValue,
highValueText: highValue,
openValueText: openValue,
closeValueText: closeValue,
lowValueText: lowValue
})
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file stockPoint.js */
(function($, DX) {
var viz = DevExpress.viz,
points = viz.core.series.points.mixins,
_extend = $.extend,
_isNumeric = $.isNumeric;
points.stockPoint = _extend({}, points.candlestickPoint, {
_getPoints: function() {
var that = this,
createPoint = that._options.rotated ? function(x, y) {
return {
x: y,
y: x
}
} : function(x, y) {
return {
x: x,
y: y
}
},
openYExist = _isNumeric(that.openY),
closeYExist = _isNumeric(that.closeY),
x = that.x,
width = that.width,
points = [createPoint(x, that.highY), openYExist && createPoint(x, that.openY), openYExist && createPoint(x - width / 2, that.openY), openYExist && createPoint(x, that.openY), closeYExist && createPoint(x, that.closeY), closeYExist && createPoint(x + width / 2, that.closeY), closeYExist && createPoint(x, that.closeY), createPoint(x, that.lowY)];
return points
},
_drawMarkerInGroup: function(group, attributes, renderer) {
this.graphic = renderer.createPath(this._getPoints(), attributes).append(group)
},
_getMinTrackerWidth: function() {
return 2 + this._styles.normal.strokeWidth
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file default.js */
(function($, DX, undefined) {
DX.viz.themes = DX.viz.themes || [];
var fontFamilyDefault = "'Segoe UI', 'Helvetica Neue', 'Trebuchet MS', Verdana",
fontFamilyLight = "'Segoe UI Light', 'Helvetica Neue Light', 'Segoe UI', 'Helvetica Neue', 'Trebuchet MS', Verdana",
baseChartTheme = {
containerBackgroundColor: '#ffffff',
animation: {
enabled: true,
duration: 1000,
easing: 'easeOutCubic',
maxPointCountSupported: 300
},
commonSeriesSettings: {
border: {
visible: false,
width: 2
},
showInLegend: true,
visible: true,
hoverMode: 'excludePoints',
selectionMode: 'includePoints',
hoverStyle: {
hatching: {
direction: 'right',
width: 2,
step: 6,
opacity: 0.75
},
border: {
visible: false,
width: 3
}
},
selectionStyle: {
hatching: {
direction: 'right',
width: 2,
step: 6,
opacity: 0.5
},
border: {
visible: false,
width: 3
}
},
label: {
visible: false,
alignment: 'center',
rotationAngle: 0,
horizontalOffset: 0,
verticalOffset: 0,
radialOffset: 0,
format: '',
argumentFormat: '',
precision: 0,
argumentPrecision: 0,
percentPrecision: 0,
showForZeroValues: true,
customizeText: undefined,
maxLabelCount: undefined,
position: 'outside',
font: {color: '#ffffff'},
border: {
visible: false,
width: 1,
color: '#d3d3d3',
dashStyle: 'solid'
},
connector: {
visible: false,
width: 1
}
}
},
redrawOnResize: true,
margin: {
left: 0,
top: 0,
right: 0,
bottom: 0
},
seriesSelectionMode: 'single',
pointSelectionMode: 'single',
legend: {
hoverMode: 'includePoints',
verticalAlignment: 'top',
horizontalAlignment: 'right',
position: 'outside',
visible: true,
customizeText: undefined,
itemTextPosition: undefined,
margin: 10,
equalColumnWidth: false,
markerSize: 12,
backgroundColor: undefined,
backgroundOpacity: undefined,
border: {
visible: false,
width: 1,
color: '#d3d3d3',
cornerRadius: 0,
dashStyle: 'solid'
},
paddingLeftRight: 20,
paddingTopBottom: 15,
columnCount: 0,
rowCount: 0,
columnItemSpacing: 20,
rowItemSpacing: 8
},
tooltip: {
enabled: false,
border: {
width: 1,
color: '#d3d3d3',
dashStyle: 'solid',
visible: true
},
font: {
family: fontFamilyDefault,
weight: 400,
size: 12,
color: '#232323'
},
color: '#ffffff',
arrowLength: 10,
paddingLeftRight: 18,
paddingTopBottom: 15,
shared: false,
format: '',
argumentFormat: '',
precision: 0,
argumentPrecision: 0,
percentPrecision: 0,
customizeText: undefined,
customizeTooltip: undefined,
shadow: {
opacity: 0.4,
offsetX: 0,
offsetY: 4,
blur: 2,
color: '#000000'
}
},
size: {
width: undefined,
height: undefined
},
loadingIndicator: {
font: {},
backgroundColor: '#ffffff',
text: 'Loading...'
},
dataPrepareSettings: {
checkTypeForAllData: false,
convertToAxisDataType: true,
sortingMethod: true
},
title: {
font: {
family: fontFamilyLight,
weight: 200,
color: '#232323',
size: 28
},
margin: 10
},
adaptiveLayout: {
width: 80,
height: 80,
keepLabels: true
},
_rtl: {legend: {itemTextPosition: 'left'}}
},
baseDarkChartTheme = {
containerBackgroundColor: '#2b2b2b',
commonSeriesSettings: {label: {border: {color: '#494949'}}},
legend: {border: {color: '#494949'}},
loadingIndicator: {backgroundColor: '#2b2b2b'},
title: {font: {color: '#929292'}},
tooltip: {
color: '#2b2b2b',
border: {color: '#494949'},
font: {color: '#929292'}
}
};
DX.viz.themes.push({
name: 'desktop',
font: {
color: '#767676',
family: fontFamilyDefault,
weight: 400,
size: 12,
cursor: 'default'
},
chart: $.extend(true, {}, baseChartTheme, {
commonSeriesSettings: {
type: 'line',
stack: 'default',
point: {
visible: true,
symbol: 'circle',
size: 12,
border: {
visible: false,
width: 1
},
hoverMode: 'onlyPoint',
selectionMode: 'onlyPoint',
hoverStyle: {
border: {
visible: true,
width: 4
},
size: 12
},
selectionStyle: {
border: {
visible: true,
width: 4
},
size: 12
}
},
scatter: {},
line: {
width: 2,
dashStyle: 'solid',
hoverStyle: {
width: 3,
hatching: {direction: 'none'}
},
selectionStyle: {width: 3}
},
stackedline: {
width: 2,
dashStyle: 'solid',
hoverStyle: {
width: 3,
hatching: {direction: 'none'}
},
selectionStyle: {width: 3}
},
fullstackedline: {
width: 2,
dashStyle: 'solid',
hoverStyle: {
width: 3,
hatching: {direction: 'none'}
},
selectionStyle: {width: 3}
},
stepline: {
width: 2,
dashStyle: 'solid',
hoverStyle: {
width: 3,
hatching: {direction: 'none'}
},
selectionStyle: {width: 3}
},
area: {
point: {visible: false},
opacity: 0.5
},
stackedarea: {
point: {visible: false},
opacity: 0.5
},
fullstackedarea: {
point: {visible: false},
opacity: 0.5
},
steparea: {
border: {
visible: true,
width: 2
},
point: {visible: false},
hoverStyle: {border: {
visible: true,
width: 3
}},
selectionStyle: {border: {
visible: true,
width: 3
}},
opacity: 0.5
},
spline: {
width: 2,
hoverStyle: {
width: 3,
hatching: {direction: 'none'}
},
selectionStyle: {width: 3}
},
splinearea: {
point: {visible: false},
opacity: 0.5
},
bar: {
cornerRadius: 0,
point: {
hoverStyle: {border: {visible: false}},
selectionStyle: {border: {visible: false}}
}
},
stackedbar: {
cornerRadius: 0,
point: {
hoverStyle: {border: {visible: false}},
selectionStyle: {border: {visible: false}}
},
label: {position: "inside"}
},
fullstackedbar: {
cornerRadius: 0,
point: {
hoverStyle: {border: {visible: false}},
selectionStyle: {border: {visible: false}}
},
label: {position: "inside"}
},
rangebar: {
cornerRadius: 0,
point: {
hoverStyle: {border: {visible: false}},
selectionStyle: {border: {visible: false}}
}
},
rangearea: {
point: {visible: false},
opacity: 0.5
},
rangesplinearea: {
point: {visible: false},
opacity: 0.5
},
bubble: {
opacity: 0.5,
point: {
hoverStyle: {border: {visible: false}},
selectionStyle: {border: {visible: false}}
}
},
candlestick: {
width: 1,
innerColor: '#ffffff',
reduction: {color: '#ff0000'},
hoverStyle: {
width: 3,
hatching: {direction: 'none'}
},
selectionStyle: {width: 3},
point: {border: {visible: true}}
},
stock: {
width: 1,
reduction: {color: '#ff0000'},
hoverStyle: {
width: 3,
hatching: {direction: 'none'}
},
selectionStyle: {width: 3},
point: {border: {visible: true}}
}
},
crosshair: {
enabled: false,
color: '#c6c6c6',
width: 1,
dashStyle: 'solid',
verticalLine: {visible: true},
horizontalLine: {visible: true}
},
commonAxisSettings: {
tickInterval: undefined,
setTicksAtUnitBeginning: true,
valueMarginsEnabled: true,
placeholderSize: null,
logarithmBase: 10,
discreteAxisDivisionMode: 'betweenLabels',
visible: false,
color: '#d3d3d3',
width: 1,
multipleAxesSpacing: 5,
label: {
visible: true,
overlappingBehavior: {
mode: 'auto',
rotationAngle: 90,
staggeringSpacing: 5
},
precision: 0,
format: '',
customizeText: undefined,
indentFromAxis: 10
},
grid: {
visible: false,
color: '#d3d3d3',
width: 1
},
tick: {
visible: false,
color: '#d3d3d3'
},
title: {
font: {size: 16},
margin: 10
},
stripStyle: {
paddingLeftRight: 10,
paddingTopBottom: 5
},
constantLineStyle: {
paddingLeftRight: 10,
paddingTopBottom: 10,
width: 1,
color: '#000000',
dashStyle: 'solid',
label: {
visible: true,
position: 'inside'
}
}
},
horizontalAxis: {
isHorizontal: true,
position: 'bottom',
axisDivisionFactor: 50,
label: {alignment: "center"},
stripStyle: {label: {
horizontalAlignment: 'center',
verticalAlignment: 'top'
}},
constantLineStyle: {label: {
horizontalAlignment: 'right',
verticalAlignment: 'top'
}},
constantLines: {}
},
verticalAxis: {
isHorizontal: false,
position: 'left',
axisDivisionFactor: 30,
label: {
alignment: 'right',
overlappingBehavior: {mode: 'enlargeTickInterval'}
},
stripStyle: {label: {
horizontalAlignment: 'left',
verticalAlignment: 'center'
}},
constantLineStyle: {label: {
horizontalAlignment: 'left',
verticalAlignment: 'top'
}},
constantLines: {}
},
argumentAxis: {},
valueAxis: {grid: {visible: true}},
commonPaneSettings: {
backgroundColor: 'none',
border: {
color: '#d3d3d3',
width: 1,
visible: false,
top: true,
bottom: true,
left: true,
right: true,
dashStyle: 'solid'
}
},
useAggregation: false,
adjustOnZoom: true,
rotated: false,
synchronizeMultiAxes: true,
equalBarWidth: true,
minBubbleSize: 12,
maxBubbleSize: 0.2
}),
pie: $.extend(true, {}, baseChartTheme, {
commonSeriesSettings: {
type: 'pie',
pie: {
border: {
visible: false,
width: 2,
color: '#ffffff'
},
hoverStyle: {
hatching: {
direction: 'right',
width: 4,
step: 10,
opacity: 0.75
},
border: {
visible: false,
width: 2
}
},
selectionStyle: {
hatching: {
direction: 'right',
width: 4,
step: 10,
opacity: 0.5
},
border: {
visible: false,
width: 2
}
}
},
doughnut: {
innerRadius: 0.5,
border: {
visible: false,
width: 2,
color: '#ffffff'
},
hoverStyle: {
hatching: {
direction: 'right',
width: 4,
step: 10,
opacity: 0.75
},
border: {
visible: false,
width: 2
}
},
selectionStyle: {
hatching: {
direction: 'right',
width: 4,
step: 10,
opacity: 0.5
},
border: {
visible: false,
width: 2
}
}
},
donut: {
innerRadius: 0.5,
border: {
visible: false,
width: 2,
color: '#ffffff'
},
hoverStyle: {
hatching: {
direction: 'right',
width: 4,
step: 10,
opacity: 0.75
},
border: {
visible: false,
width: 2
}
},
selectionStyle: {
hatching: {
direction: 'right',
width: 4,
step: 10,
opacity: 0.5
},
border: {
visible: false,
width: 2
}
}
}
},
legend: {hoverMode: 'markPoint'},
adaptiveLayout: {keepLabels: false}
}),
pieIE8: {commonSeriesSettings: {
pie: {
hoverStyle: {border: {
visible: true,
color: '#ffffff'
}},
selectionStyle: {border: {
visible: true,
color: '#ffffff'
}}
},
donut: {
hoverStyle: {border: {
visible: true,
color: '#ffffff'
}},
selectionStyle: {border: {
visible: true,
color: '#ffffff'
}}
},
doughnut: {
hoverStyle: {border: {
visible: true,
color: '#ffffff'
}},
selectionStyle: {border: {
visible: true,
color: '#ffffff'
}}
}
}},
gauge: {
containerBackgroundColor: '#ffffff',
scale: {
majorTick: {
visible: true,
length: 5,
width: 2,
showCalculatedTicks: true,
useTicksAutoArrangement: true,
color: '#ffffff'
},
minorTick: {
visible: false,
length: 3,
width: 1,
showCalculatedTicks: true,
color: '#ffffff'
},
label: {
visible: true,
font: {}
}
},
rangeContainer: {
offset: 0,
width: 5,
backgroundColor: '#808080'
},
valueIndicator: {
_default: {color: '#c2c2c2'},
rangebar: {
space: 2,
size: 10,
color: '#cbc5cf',
backgroundColor: 'none',
text: {
indent: 0,
font: {
size: 14,
color: null
}
}
},
twocolorneedle: {secondColor: '#e18e92'},
twocolorrectangle: {secondColor: '#e18e92'}
},
subvalueIndicator: {
_default: {color: '#8798a5'},
trianglemarker: {
space: 2,
length: 14,
width: 13,
color: '#8798a5'
},
triangle: {
space: 2,
length: 14,
width: 13,
color: '#8798a5'
},
textcloud: {
arrowLength: 5,
horizontalOffset: 6,
verticalOffset: 3,
color: '#679ec5',
text: {font: {
color: '#ffffff',
size: 18
}}
}
},
valueIndicators: {
_default: {color: '#c2c2c2'},
rangebar: {
space: 2,
size: 10,
color: '#cbc5cf',
backgroundColor: 'none',
text: {
indent: 0,
font: {
size: 14,
color: null
}
}
},
twocolorneedle: {secondColor: '#e18e92'},
trianglemarker: {
space: 2,
length: 14,
width: 13,
color: '#8798a5'
},
textcloud: {
arrowLength: 5,
horizontalOffset: 6,
verticalOffset: 3,
color: '#679ec5',
text: {font: {
color: '#ffffff',
size: 18
}}
}
},
title: {
layout: {
horizontalAlignment: 'center',
verticalAlignment: 'top',
overlay: 0
},
font: {
size: 16,
color: '#232323',
family: fontFamilyDefault,
weight: 400
}
},
subtitle: {font: {
size: 14,
color: '#232323',
family: fontFamilyDefault,
weight: 400
}},
indicator: {
hasPositiveMeaning: true,
layout: {
horizontalAlignment: 'center',
verticalAlignment: 'bottom',
overlay: 0
},
text: {font: {size: 18}}
},
tooltip: {
arrowLength: 10,
paddingLeftRight: 18,
paddingTopBottom: 15,
enabled: false,
border: {
width: 1,
color: '#d3d3d3',
dashStyle: 'solid',
visible: true
},
color: '#ffffff',
font: {
color: '#232323',
size: 12,
family: fontFamilyDefault,
weight: 400
},
shadow: {
opacity: 0.4,
offsetX: 0,
offsetY: 4,
blur: 2,
color: '#000000'
}
},
loadingIndicator: {
font: {},
backgroundColor: '#ffffff',
text: 'Loading...'
},
_circular: {
scale: {
orientation: 'outside',
label: {indentFromTick: 10}
},
rangeContainer: {orientation: 'outside'},
valueIndicator: {
type: 'rectangleneedle',
_default: {
offset: 20,
indentFromCenter: 0,
width: 2,
spindleSize: 14,
spindleGapSize: 10
},
triangleneedle: {width: 4},
triangle: {width: 4},
twocolorneedle: {
space: 2,
secondFraction: 0.4
},
twocolorrectangle: {
space: 2,
secondFraction: 0.4
},
rangebar: {offset: 30}
},
subvalueIndicator: {
type: 'trianglemarker',
trianglemarker: {offset: 6},
triangle: {offset: 6},
textcloud: {offset: -6}
},
valueIndicators: {
_type: 'rectangleneedle',
_default: {
offset: 20,
indentFromCenter: 0,
width: 2,
spindleSize: 14,
spindleGapSize: 10
},
triangleneedle: {width: 4},
twocolorneedle: {
space: 2,
secondFraction: 0.4
},
rangebar: {offset: 30},
trianglemarker: {offset: 6},
textcloud: {offset: -6}
}
},
_linear: {
scale: {
horizontalOrientation: 'right',
verticalOrientation: 'bottom',
label: {indentFromTick: -10}
},
rangeContainer: {
horizontalOrientation: 'right',
verticalOrientation: 'bottom'
},
valueIndicator: {
type: 'rangebar',
_default: {
offset: 2.5,
length: 15,
width: 15
},
rectangle: {width: 10},
rangebar: {
offset: 10,
horizontalOrientation: 'right',
verticalOrientation: 'bottom'
}
},
subvalueIndicator: {
type: 'trianglemarker',
_default: {
offset: -1,
horizontalOrientation: 'left',
verticalOrientation: 'top'
}
},
valueIndicators: {
_type: 'rectangle',
_default: {
offset: 2.5,
length: 15,
width: 15
},
rectangle: {width: 10},
rangebar: {
offset: 10,
horizontalOrientation: 'right',
verticalOrientation: 'bottom'
},
trianglemarker: {
offset: -1,
horizontalOrientation: 'left',
verticalOrientation: 'top'
},
textcloud: {
offset: -1,
horizontalOrientation: 'left',
verticalOrientation: 'top'
}
}
}
},
barGauge: {
backgroundColor: '#e0e0e0',
relativeInnerRadius: 0.3,
barSpacing: 4,
label: {
indent: 20,
connectorWidth: 2,
font: {size: 16}
},
title: {
layout: {
horizontalAlignment: 'center',
verticalAlignment: 'top',
overlay: 0
},
font: {
size: 16,
color: '#232323',
family: fontFamilyDefault,
weight: 400
}
},
subtitle: {font: {
size: 14,
color: '#232323',
family: fontFamilyDefault,
weight: 400
}},
indicator: {
hasPositiveMeaning: true,
layout: {
horizontalAlignment: 'center',
verticalAlignment: 'bottom',
overlay: 0
},
text: {font: {size: 18}}
},
tooltip: {
arrowLength: 10,
paddingLeftRight: 18,
paddingTopBottom: 15,
enabled: false,
border: {
width: 1,
color: '#d3d3d3',
dashStyle: 'solid',
visible: true
},
color: '#ffffff',
font: {
size: 12,
color: '#232323',
family: fontFamilyDefault,
weight: 400
},
shadow: {
opacity: 0.4,
offsetX: 0,
offsetY: 4,
blur: 2,
color: '#000000'
}
},
loadingIndicator: {
font: {},
backgroundColor: '#ffffff',
text: 'Loading...'
}
},
rangeSelector: {
containerBackgroundColor: '#ffffff',
scale: {
label: {
topIndent: 7,
font: {size: 11}
},
tick: {
width: 1,
color: '#000000',
opacity: 0.1
},
marker: {
separatorHeight: 33,
topIndent: 10,
textLeftIndent: 7,
textTopIndent: 11
}
},
loadingIndicator: {
font: {},
backgroundColor: '#ffffff',
text: 'Loading...'
},
sliderMarker: {
padding: 7,
pointerSize: 6,
color: '#9b9b9b',
invalidRangeColor: '#ff0000',
font: {
color: '#ffffff',
size: 11
}
},
sliderHandle: {
width: 1,
color: '#000000',
opacity: 0.2
},
shutter: {
color: undefined,
opacity: 0.75
},
background: {color: "#c0bae1"},
chart: {
containerBackgroundColor: undefined,
commonSeriesSettings: {
label: baseChartTheme.commonSeriesSettings.label,
border: {
visible: false,
width: 1
},
visible: true,
type: 'area',
hoverMode: 'none',
hoverStyle: {border: {}},
selectionStyle: {border: {}},
point: {
visible: false,
symbol: 'circle',
border: {
visible: false,
width: 1
},
size: 12,
hoverStyle: {border: {}},
selectionStyle: {border: {}}
},
line: {width: 2},
stepline: {width: 2},
scatter: {point: {visible: true}},
stackedline: {width: 2},
fullstackedline: {width: 2},
area: {opacity: 0.5},
stackedarea: {opacity: 0.5},
fullstackedarea: {opacity: 0.5},
spline: {width: 2},
splinearea: {opacity: 0.5},
steparea: {
border: {
visible: true,
width: 2
},
opacity: 0.5
},
bubble: {
opacity: 0.5,
point: {visible: true}
},
bar: {
cornerRadius: 0,
point: {visible: true}
},
stackedbar: {
cornerRadius: 0,
point: {visible: true}
},
fullstackedbar: {
cornerRadius: 0,
point: {visible: true}
},
rangebar: {
cornerRadius: 0,
point: {visible: true}
},
rangearea: {opacity: 0.5},
rangesplinearea: {opacity: 0.5},
candlestick: {
width: 1,
innerColor: '#ffffff',
reduction: {color: '#ff0000'}
},
stock: {
width: 1,
reduction: {color: '#ff0000'}
}
},
dataPrepareSettings: {
checkTypeForAllData: false,
convertToAxisDataType: true,
sortingMethod: true
},
useAggregation: false,
equalBarWidth: true,
minBubbleSize: 12,
maxBubbleSize: 0.2,
topIndent: 0.1,
bottomIndent: 0,
valueAxis: {
min: undefined,
max: undefined,
inverted: false,
logarithmBase: 10
}
}
},
map: {
background: {
borderWidth: 1,
borderColor: '#cacaca',
color: '#ffffff'
},
area: {
borderWidth: 1,
borderColor: '#ffffff',
color: '#d2d2d2',
hoveredBorderColor: '#303030',
selectedBorderWidth: 2,
selectedBorderColor: '#303030'
},
marker: {
font: {
color: '#2b2b2b',
size: 12
},
_dot: {
borderWidth: 2,
borderColor: '#ffffff',
color: '#ba4d51',
size: 8,
selectedStep: 2,
backStep: 18,
backColor: '#ffffff',
backOpacity: 0.32,
shadow: true
},
_bubble: {
minSize: 20,
maxSize: 50,
color: '#ba4d51',
hoveredBorderWidth: 1,
hoveredBorderColor: '#303030',
selectedBorderWidth: 2,
selectedBorderColor: '#303030'
},
_pie: {
size: 50,
hoveredBorderWidth: 1,
hoveredBorderColor: '#303030',
selectedBorderWidth: 2,
selectedBorderColor: '#303030'
},
_image: {size: 20}
},
controlBar: {
borderColor: '#5d5d5d',
borderWidth: 3,
color: '#ffffff'
},
tooltip: {
borderWidth: 1,
borderColor: '#d7d7d7',
arrowLength: 10,
paddingLeftRight: 18,
paddingTopBottom: 15,
border: {
width: 1,
color: '#d3d3d3',
dashStyle: 'solid',
visible: true
},
color: '#ffffff',
font: {
color: '#232323',
size: 12,
family: fontFamilyDefault,
weight: 400
},
shadow: {
opacity: 0.4,
offsetX: 0,
offsetY: 4,
blur: 2,
color: '#000000'
}
},
legend: {
verticalAlignment: 'bottom',
horizontalAlignment: 'right',
position: 'inside',
visible: true,
margin: 10,
equalColumnWidth: false,
markerSize: 12,
backgroundColor: '#ffffff',
backgroundOpacity: 0.65,
border: {
visible: true,
width: 1,
color: '#cacaca',
cornerRadius: 0,
dashStyle: 'solid'
},
paddingLeftRight: 16,
paddingTopBottom: 12,
columnItemSpacing: 20,
rowItemSpacing: 8,
font: {
color: '#2b2b2b',
size: 12
}
},
loadingIndicator: {
backgroundColor: '#ffffff',
font: {},
text: 'Loading...'
},
_rtl: {legend: {itemTextPosition: 'left'}}
},
sparkline: {
lineColor: '#666666',
lineWidth: 2,
areaOpacity: 0.2,
minColor: '#e8c267',
maxColor: '#e55253',
barPositiveColor: '#a9a9a9',
barNegativeColor: '#d7d7d7',
winColor: '#a9a9a9',
lossColor: '#d7d7d7',
firstLastColor: '#666666',
pointSymbol: 'circle',
pointColor: '#ffffff',
pointSize: 4,
tooltip: {
enabled: true,
allowContainerResizing: true,
verticalAlignment: 'top',
horizontalAlignment: 'center',
format: '',
paddingLeftRight: 18,
paddingTopBottom: 15,
arrowLength: 10,
precision: 0,
color: '#ffffff',
border: {
width: 1,
color: '#d3d3d3',
dashStyle: 'solid',
visible: true
},
font: {
color: '#232323',
family: fontFamilyDefault,
size: 12,
weight: 400
},
shadow: {
opacity: 0.4,
offsetX: 0,
offsetY: 4,
blur: 2,
color: '#000000'
}
}
},
bullet: {
color: '#e8c267',
targetColor: '#666666',
targetWidth: 4,
showTarget: true,
showZeroLevel: true,
tooltip: {
enabled: true,
allowContainerResizing: true,
verticalAlignment: 'top',
horizontalAlignment: 'center',
format: '',
precision: 0,
paddingLeftRight: 18,
paddingTopBottom: 15,
arrowLength: 10,
color: '#ffffff',
border: {
width: 1,
color: '#d3d3d3',
dashStyle: 'solid',
visible: true
},
font: {
color: '#232323',
family: fontFamilyDefault,
size: 12,
weight: 400
},
shadow: {
opacity: 0.4,
offsetX: 0,
offsetY: 4,
blur: 2,
color: '#000000'
}
}
}
});
DX.viz.core.registerTheme({
name: 'desktop-dark',
font: {color: '#808080'},
chart: $.extend(true, {}, baseDarkChartTheme, {
commonSeriesSettings: {candlestick: {innerColor: '#2b2b2b'}},
crosshair: {color: '#515151'},
commonAxisSettings: {
color: '#494949',
grid: {color: '#494949'},
tick: {color: '#494949'},
constantLineStyle: {color: '#ffffff'}
},
commonPaneSettings: {border: {color: '#494949'}}
}),
pie: $.extend(true, {}, baseDarkChartTheme),
pieIE8: {commonSeriesSettings: {
pie: {
hoverStyle: {border: {color: '#2b2b2b'}},
selectionStyle: {border: {color: '#2b2b2b'}}
},
donut: {
hoverStyle: {border: {color: '#2b2b2b'}},
selectionStyle: {border: {color: '#2b2b2b'}}
},
doughnut: {
hoverStyle: {border: {color: '#2b2b2b'}},
selectionStyle: {border: {color: '#2b2b2b'}}
}
}},
gauge: {
containerBackgroundColor: '#2b2b2b',
scale: {
majorTick: {color: '#303030'},
minorTick: {color: '#303030'}
},
rangeContainer: {backgroundColor: '#b5b5b5'},
valueIndicator: {
_default: {color: '#b5b5b5'},
rangebar: {color: '#84788b'},
twocolorneedle: {secondColor: '#ba544d'},
twocolorrectangle: {secondColor: '#ba544d'}
},
subvalueIndicator: {_default: {color: '#b7918f'}},
valueIndicators: {
_default: {color: '#b5b5b5'},
rangebar: {color: '#84788b'},
twocolorneedle: {secondColor: '#ba544d'},
trianglemarker: {color: '#b7918f'},
textcloud: {color: '#ba544d'}
},
title: {font: {color: '#929292'}},
subtitle: {font: {color: '#929292'}},
loadingIndicator: {backgroundColor: '#2b2b2b'},
tooltip: {
color: '#2b2b2b',
border: {color: '#494949'},
font: {color: '#929292'}
}
},
barGauge: {
title: {font: {color: '#929292'}},
subtitle: {font: {color: '#929292'}},
tooltip: {
color: '#2b2b2b',
border: {color: '#494949'},
font: {color: '#929292'}
},
loadingIndicator: {backgroundColor: '#2b2b2b'}
},
rangeSelector: {
containerBackgroundColor: '#2b2b2b',
scale: {tick: {
color: '#ffffff',
opacity: 0.05
}},
loadingIndicator: {backgroundColor: '#2b2b2b'},
sliderMarker: {
color: '#b5b5b5',
font: {color: '#303030'}
},
sliderHandle: {
color: '#ffffff',
opacity: 0.35
},
shutter: {
color: '#2b2b2b',
opacity: 0.9
}
},
map: {
background: {
borderColor: '#3f3f3f',
color: '#303030'
},
area: {
borderColor: '#303030',
color: '#686868',
hoveredBorderColor: '#ffffff',
selectedBorderColor: '#ffffff'
},
marker: {
font: {color: '#ffffff'},
_bubble: {
hoveredBorderColor: '#ffffff',
selectedBorderColor: '#ffffff'
},
_pie: {
hoveredBorderColor: '#ffffff',
selectedBorderColor: '#ffffff'
}
},
controlBar: {
borderColor: '#c7c7c7',
color: '#303030'
},
legend: {
border: {color: '#3f3f3f'},
backgroundColor: '#303030',
font: {color: '#ffffff'}
},
tooltip: {
color: '#2b2b2b',
border: {color: '#494949'},
font: {color: '#929292'}
},
loadingIndicator: {backgroundColor: '#2b2b2b'}
},
sparkline: {
lineColor: '#c7c7c7',
firstLastColor: '#c7c7c7',
barPositiveColor: '#b8b8b8',
barNegativeColor: '#8e8e8e',
winColor: '#b8b8b8',
lossColor: '#8e8e8e',
pointColor: '#303030',
tooltip: {
color: '#2b2b2b',
border: {color: '#494949'},
font: {color: '#929292'}
}
},
bullet: {
targetColor: '#8e8e8e',
tooltip: {
color: '#2b2b2b',
border: {color: '#494949'},
font: {color: '#929292'}
}
}
}, 'desktop')
})(jQuery, DevExpress);
/*! Module viz-core, file android.js */
(function($, DX, undefined) {
var baseChartTheme = {
containerBackgroundColor: '#050506',
title: {font: {color: '#ffffff'}},
commonSeriesSettings: {label: {border: {color: '#4c4c4c'}}},
legend: {
font: {
color: '#ffffff',
size: 11
},
border: {color: '#4c4c4c'}
},
loadingIndicator: {backgroundColor: '#050506'},
tooltip: {
color: '#050506',
border: {color: '#4c4c4c'},
font: {color: '#ffffff'}
}
},
baseLightChartTheme = {
containerBackgroundColor: '#e8e8e8',
title: {font: {color: '#808080'}},
legend: {font: {
color: '#000000',
size: 11
}},
loadingIndicator: {backgroundColor: '#e8e8e8'},
tooltip: {
color: '#e8e8e8',
font: {color: '#808080'}
}
};
DX.viz.core.registerTheme({
name: 'android',
chart: $.extend(true, {}, baseChartTheme, {
commonSeriesSettings: {candlestick: {innerColor: '#050506'}},
commonAxisSettings: {
color: '#4c4c4c',
grid: {color: '#4c4c4c'},
tick: {color: '#4c4c4c'},
title: {font: {color: '#545455'}},
label: {font: {
color: '#ffffff',
size: 11
}}
},
commonPaneSettings: {border: {color: '#4c4c4c'}}
}),
pie: $.extend(true, {}, baseChartTheme),
pieIE8: {commonSeriesSettings: {
pie: {
hoverStyle: {border: {color: '#050506'}},
selectionStyle: {border: {color: '#050506'}}
},
donut: {
hoverStyle: {border: {color: '#050506'}},
selectionStyle: {border: {color: '#050506'}}
},
doughnut: {
hoverStyle: {border: {color: '#050506'}},
selectionStyle: {border: {color: '#050506'}}
}
}},
gauge: {
containerBackgroundColor: '#050506',
title: {font: {color: '#ffffff'}},
subtitle: {font: {color: '#ffffff'}},
loadingIndicator: {backgroundColor: '#050506'},
tooltip: {
color: '#050506',
border: {color: '#4c4c4c'},
font: {color: '#ffffff'}
}
},
barGauge: {
title: {font: {color: '#ffffff'}},
subtitle: {font: {color: '#ffffff'}},
tooltip: {
color: '#050506',
border: {color: '#4c4c4c'},
font: {color: '#ffffff'}
},
loadingIndicator: {backgroundColor: '#050506'}
},
rangeSelector: {
containerBackgroundColor: '#050506',
loadingIndicator: {backgroundColor: '#050506'}
},
map: {
loadingIndicator: {backgroundColor: '#050506'},
tooltip: {
color: '#050506',
border: {color: '#4c4c4c'},
font: {color: '#ffffff'}
}
},
sparkline: {tooltip: {
color: '#050506',
border: {color: '#4c4c4c'},
font: {color: '#ffffff'}
}},
bullet: {tooltip: {
color: '#050506',
border: {color: '#4c4c4c'},
font: {color: '#ffffff'}
}}
}, 'desktop-dark');
DX.viz.core.registerTheme({
name: 'android-holo-light',
chart: $.extend(true, {}, baseLightChartTheme, {
commonSeriesSettings: {candlestick: {innerColor: '#e8e8e8'}},
commonAxisSettings: {
title: {font: {color: '#939393'}},
label: {font: {
color: '#404040',
size: 11
}}
}
}),
pie: $.extend(true, {}, baseLightChartTheme),
pieIE8: {commonSeriesSettings: {
pie: {
hoverStyle: {border: {color: '#e8e8e8'}},
selectionStyle: {border: {color: '#e8e8e8'}}
},
donut: {
hoverStyle: {border: {color: '#e8e8e8'}},
selectionStyle: {border: {color: '#e8e8e8'}}
},
doughnut: {
hoverStyle: {border: {color: '#e8e8e8'}},
selectionStyle: {border: {color: '#e8e8e8'}}
}
}},
gauge: {
containerBackgroundColor: '#e8e8e8',
title: {font: {color: '#808080'}},
subtitle: {font: {color: '#808080'}},
loadingIndicator: {backgroundColor: '#e8e8e8'},
tooltip: {
color: '#e8e8e8',
font: {color: '#808080'}
}
},
barGauge: {
title: {font: {color: '#808080'}},
subtitle: {font: {color: '#808080'}},
tooltip: {
color: '#e8e8e8',
font: {color: '#808080'}
},
loadingIndicator: {backgroundColor: '#e8e8e8'}
},
rangeSelector: {
containerBackgroundColor: '#e8e8e8',
loadingIndicator: {backgroundColor: '#e8e8e8'}
},
map: {
loadingIndicator: {backgroundColor: '#e8e8e8'},
tooltip: {
color: '#e8e8e8',
font: {color: '#808080'}
}
},
sparkline: {tooltip: {
color: '#e8e8e8',
font: {color: '#808080'}
}},
bullet: {tooltip: {
color: '#e8e8e8',
font: {color: '#808080'}
}}
}, 'desktop')
})(jQuery, DevExpress);
/*! Module viz-core, file ios.js */
(function($, DX, undefined) {
var baseChartTheme = {
containerBackgroundColor: '#cbd0da',
title: {font: {color: '#808080'}},
commonSeriesSettings: {label: {border: {color: '#b0b3ba'}}},
legend: {
font: {
color: '#000000',
size: 11
},
border: {color: '#b0b3ba'}
},
loadingIndicator: {backgroundColor: '#cbd0da'},
tooltip: {font: {color: '#808080'}}
},
baseIos7ChartTheme = {
containerBackgroundColor: '#ffffff',
title: {font: {color: '#808080'}},
commonSeriesSettings: {label: {border: {color: '#d3d3d3'}}},
legend: {
font: {
color: '#000000',
size: 11
},
border: {color: '#d3d3d3'}
},
loadingIndicator: {backgroundColor: '#ffffff'},
tooltip: {font: {color: '#808080'}}
};
DX.viz.core.registerTheme({
name: 'ios',
chart: $.extend(true, {}, baseChartTheme, {
commonSeriesSettings: {candlestick: {innerColor: '#cbd0da'}},
commonAxisSettings: {
color: '#b0b3ba',
grid: {color: '#b0b3ba'},
tick: {color: '#b0b3ba'},
title: {font: {color: '#939393'}},
label: {font: {
color: '#000000',
size: 11
}}
},
commonPaneSettings: {border: {color: '#b0b3ba'}}
}),
pie: $.extend(true, {}, baseChartTheme),
pieIE8: {commonSeriesSettings: {
pie: {
hoverStyle: {border: {color: '#cbd0da'}},
selectionStyle: {border: {color: '#cbd0da'}}
},
donut: {
hoverStyle: {border: {color: '#cbd0da'}},
selectionStyle: {border: {color: '#cbd0da'}}
},
doughnut: {
hoverStyle: {border: {color: '#cbd0da'}},
selectionStyle: {border: {color: '#cbd0da'}}
}
}},
gauge: {
title: {font: {color: '#808080'}},
subtitle: {font: {color: '#808080'}},
tooltip: {font: {color: '#808080'}}
},
barGauge: {
title: {font: {color: '#808080'}},
subtitle: {font: {color: '#808080'}},
tooltip: {font: {color: '#808080'}}
},
map: {tooltip: {font: {color: '#808080'}}},
sparkline: {tooltip: {font: {color: '#808080'}}},
bullet: {tooltip: {font: {color: '#808080'}}}
}, 'desktop');
DX.viz.core.registerTheme({
name: 'ios:7',
chart: $.extend(true, {}, baseIos7ChartTheme, {
commonAxisSettings: {
color: '#d3d3d3',
grid: {color: '#d3d3d3'},
tick: {color: '#d3d3d3'},
title: {font: {color: '#939393'}},
label: {font: {
color: '#000000',
size: 11
}}
},
commonPaneSettings: {border: {color: '#d3d3d3'}}
}),
pie: $.extend(true, {}, baseIos7ChartTheme),
gauge: {
title: {font: {color: '#808080'}},
subtitle: {font: {color: '#808080'}},
tooltip: {font: {color: '#808080'}}
},
barGauge: {
title: {font: {color: '#808080'}},
subtitle: {font: {color: '#808080'}},
tooltip: {font: {color: '#808080'}}
},
map: {tooltip: {font: {color: '#808080'}}},
sparkline: {tooltip: {font: {color: '#808080'}}},
bullet: {tooltip: {font: {color: '#808080'}}}
}, 'desktop')
})(jQuery, DevExpress);
/*! Module viz-core, file win8.js */
(function($, DX) {
var baseChartTheme = {
containerBackgroundColor: '#000000',
title: {font: {color: '#ffffff'}},
commonSeriesSettings: {label: {border: {color: '#454545'}}},
legend: {
font: {
color: '#ffffff',
size: 11
},
border: {color: '#454545'}
},
loadingIndicator: {backgroundColor: '#000000'},
tooltip: {
color: '#000000',
font: {color: '#ffffff'}
}
},
baseWhiteChartTheme = {
title: {font: {color: '#808080'}},
legend: {font: {
color: '#000000',
size: 11
}},
tooltip: {font: {color: '#808080'}}
};
DX.viz.core.registerTheme({
name: 'win8',
chart: $.extend(true, {}, baseChartTheme, {
commonSeriesSettings: {candlestick: {innerColor: '#000000'}},
commonAxisSettings: {
color: '#454545',
grid: {color: '#454545'},
tick: {color: '#454545'},
title: {font: {color: '#535353'}},
label: {font: {
color: '#ffffff',
size: 11
}}
},
commonPaneSettings: {border: {color: '#454545'}}
}),
pie: $.extend(true, {}, baseChartTheme),
pieIE8: {commonSeriesSettings: {
pie: {
hoverStyle: {border: {color: '#000000'}},
selectionStyle: {border: {color: '#000000'}}
},
donut: {
hoverStyle: {border: {color: '#000000'}},
selectionStyle: {border: {color: '#000000'}}
},
doughnut: {
hoverStyle: {border: {color: '#000000'}},
selectionStyle: {border: {color: '#000000'}}
}
}},
gauge: {
containerBackgroundColor: '#000000',
title: {font: {color: '#ffffff'}},
subtitle: {font: {color: '#ffffff'}},
loadingIndicator: {backgroundColor: '#000000'},
tooltip: {
color: '#000000',
font: {color: '#ffffff'}
}
},
barGauge: {
title: {font: {color: '#ffffff'}},
subtitle: {font: {color: '#ffffff'}},
tooltip: {
color: '#000000',
font: {color: '#ffffff'}
},
loadingIndicator: {backgroundColor: '#000000'}
},
rangeSelector: {
containerBackgroundColor: '#000000',
loadingIndicator: {backgroundColor: '#000000'}
},
map: {
loadingIndicator: {backgroundColor: '#000000'},
tooltip: {
color: '#000000',
font: {color: '#ffffff'}
}
},
sparkline: {tooltip: {
color: '#000000',
font: {color: '#ffffff'}
}},
bullet: {tooltip: {
color: '#000000',
font: {color: '#ffffff'}
}}
}, 'desktop-dark');
DX.viz.core.registerTheme({
name: 'win8-white',
chart: $.extend(true, {}, baseWhiteChartTheme, {commonAxisSettings: {
title: {font: {color: '#939393'}},
label: {font: {
color: '#404040',
size: 11
}}
}}),
pie: $.extend(true, {}, baseWhiteChartTheme),
gauge: {
title: {font: {color: '#808080'}},
subtitle: {font: {color: '#808080'}},
tooltip: {font: {color: '#808080'}}
},
barGauge: {
title: {font: {color: '#808080'}},
subtitle: {font: {color: '#808080'}},
tooltip: {font: {color: '#808080'}}
},
map: {tooltip: {font: {color: '#808080'}}},
sparkline: {tooltip: {font: {color: '#808080'}}},
bullet: {tooltip: {font: {color: '#808080'}}}
}, 'desktop')
})(jQuery, DevExpress);
/*! Module viz-core, file others.js */
(function($, DX) {
DX.viz.core.registerTheme({name: 'generic'}, 'desktop');
DX.viz.core.registerTheme({name: 'generic-dark'}, 'desktop-dark');
DX.viz.core.registerTheme({name: 'tizen'}, 'desktop');
DX.viz.core.registerTheme({name: 'tizen-black'}, 'desktop-dark')
})(jQuery, DevExpress);
/*! Module viz-core, file namespaces.js */
(function(DevExpress) {
DevExpress.viz.renderers = {}
})(DevExpress);
/*! Module viz-core, file svgRenderer.js */
(function($, DX) {
var renderers = DX.viz.renderers,
utils = DX.utils,
Class = DX.Class,
doc = document,
MAX_PIXEL_COUNT = 10000000000;
function createElement(name) {
return doc.createElementNS('http://www.w3.org/2000/svg', name)
}
function getPatternUrl(id, pathModified) {
return id !== null ? 'url(' + (pathModified ? window.location.href : '') + '#' + id + ')' : null
}
var BaseSvgElement = Class.inherit({
ctor: function baseSvgElementCtor(renderer, name, params) {
this.renderer = renderer;
this.element = this.createElement(name);
this.$element = $(this.element);
this.applySettings($.extend({}, this.defaultSettings(), params));
this.__passedParams = params
},
defaultSettings: $.noop,
createElement: function(nodeName) {
this._nodeName = nodeName;
return createElement(nodeName)
},
dispose: function() {
this.off();
this.remove();
this.renderer = null;
this.element = null;
this.settings = null;
this.$element = null;
this.transformation = null;
this.__passedParams = null;
this.__appliedSettings = null;
this.__appliedStyle = null
},
append: function(svgElement) {
var toElement = svgElement || this.renderer.getRoot();
toElement.element.appendChild(this.element);
return this
},
insertBefore: function(target) {
target.element.parentNode.insertBefore(this.element, target.element);
return this
},
toBackground: function() {
this.element.parentNode && this.element.parentNode.insertBefore(this.element, this.element.parentNode.firstChild);
return this
},
toForeground: function() {
this.element.parentNode && this.element.parentNode.appendChild(this.element);
return this
},
addClass: function(className) {
var classAttribute = this.$element.attr('class'),
classNameIndex,
classNames;
if (className) {
if (classAttribute) {
classNames = classAttribute.split(' ');
classNameIndex = $.inArray(className, classNames);
if (classNameIndex === -1)
classAttribute += ' ' + className
}
else
classAttribute = className;
this.$element.attr('class', classAttribute)
}
return this.$element
},
removeClass: function(className) {
var classAttribute = this.$element.attr('class'),
classNames,
indexDeleteElement,
resultClassNames = '',
i;
if (classAttribute && className) {
classNames = classAttribute.split(' ');
indexDeleteElement = $.inArray(className, classNames);
if (indexDeleteElement !== -1) {
for (i = 0; i < classNames.length; i++)
if (i !== indexDeleteElement)
resultClassNames += classNames[i] + ' ';
this.$element.attr('class', resultClassNames.replace(/ $/, ''))
}
}
return this.$element
},
applySettings: function(settings) {
var normalized;
this.settings = $.extend(this.settings || {}, settings || {});
this.adjustSettings();
normalized = this._normalizeSettings(this.settings);
this.applyStyle(this._style);
this._applyAttributes(normalized);
return this
},
_applyAttributes: function(settings) {
this.$element.attr(settings);
this.__appliedSettings = settings
},
adjustSettings: function(){},
applyStyle: function(style) {
this.$element.css(style || {});
this.__appliedStyle = style || {};
return this
},
trigger: function(event, data) {
this.$element.trigger(event, data)
},
on: function(events, data, handler) {
this.$element.on.apply(this.$element, arguments);
return this
},
data: function(key, value) {
this.$element.data(key, value);
return this
},
removeData: function() {
this.$element.removeData();
return this
},
off: function(events) {
this.$element.off(events);
return this
},
getBBox: function() {
var that = this,
bBox,
element = this.element,
transformation = that.transformation,
rotateAngle = transformation.rotateAngle || 0,
rotateX = transformation.rotateX || 0,
rotateY = transformation.rotateY || 0,
mabs = Math.abs,
mmin = Math.min;
function bBox(el) {
var ret = {};
try {
if (!$.isFunction(el.getBBox))
throw{};
else
ret = el.getBBox()
}
catch(e) {
ret = {
x: 0,
y: 0,
width: el.offsetWidth || 0,
height: el.offsetHeight || 0
}
}
return ret
}
bBox = $.extend({}, bBox(element));
if (rotateAngle) {
var cossin = utils.getCosAndSin(rotateAngle),
sin = cossin.sin.toFixed(3),
cos = cossin.cos.toFixed(3),
ltx = bBox.x - rotateX,
lty = bBox.y - rotateY,
rtx = bBox.x + bBox.width - rotateX,
rty = bBox.y - rotateY,
lbx = bBox.x - rotateX,
lby = bBox.y + bBox.height - rotateY,
rbx = bBox.x + bBox.width - rotateX,
rby = bBox.y + bBox.height - rotateY,
w,
h;
w = mabs(bBox.height * sin) + mabs(bBox.width * cos);
h = mabs(bBox.height * cos) + mabs(bBox.width * sin);
bBox.x = mmin(ltx * cos - lty * sin + rotateX, rtx * cos - rty * sin + rotateX, lbx * cos - lby * sin + rotateX, rbx * cos - rby * sin + rotateX);
bBox.y = mmin(ltx * sin + lty * cos + rotateY, rtx * sin + rty * cos + rotateY, lbx * sin + lby * cos + rotateY, rbx * sin + rby * cos + rotateY);
bBox.width = w;
bBox.height = h
}
return that._normalizeBBox(bBox)
},
_normalizeBBox: function(bBox) {
var ceil = Math.ceil,
floor = Math.floor,
$isNumeric = $.isNumeric,
rxl = floor(bBox.x),
ryt = floor(bBox.y),
rxr = ceil(bBox.width + bBox.x),
ryb = ceil(bBox.height + bBox.y),
width,
height;
bBox.x = $isNumeric(rxl) && rxl < MAX_PIXEL_COUNT && rxl > -MAX_PIXEL_COUNT ? rxl : 0;
bBox.y = $isNumeric(ryt) && ryt < MAX_PIXEL_COUNT && ryt > -MAX_PIXEL_COUNT ? ryt : 0;
width = rxr - rxl;
height = ryb - ryt;
bBox.width = $isNumeric(width) && width < MAX_PIXEL_COUNT && width > -MAX_PIXEL_COUNT ? width : 0;
bBox.height = $isNumeric(height) && height < MAX_PIXEL_COUNT && height > -MAX_PIXEL_COUNT ? height : 0;
bBox.isEmpty = !bBox.x && !bBox.y && !bBox.width && !bBox.height;
return bBox
},
clear: function(selector) {
selector ? this.$element.find(selector).remove() : this.$element.empty();
return this
},
detach: function() {
this.$element.detach();
return this
},
animate: function(params, options, complete) {
options = options || {};
var that = this,
animationParams = {};
if (complete)
$.extend(options, {complete: complete});
if (this.renderer.animOptions.enabled) {
$.each(params, function(name, to) {
switch (name) {
case'scale':
animationParams['transform'] = animationParams['transform'] || {};
var scale = that.transformation.scale || {};
animationParams['transform'].scale = {
x: {
from: utils.isDefined(scale.x) ? scale.x : 1,
to: utils.isDefined(to.x) ? to.x : 1
},
y: {
from: utils.isDefined(scale.y) ? scale.y : 1,
to: utils.isDefined(to.y) ? to.y : 1
}
};
break;
case'rotate':
animationParams['transform'] = animationParams['transform'] || {};
animationParams['transform'].rotate = {
angle: {
from: that.transformation.rotateAngle || 0,
to: to.angle
},
y: to.y || 0,
x: to.x || 0
};
break;
case'translate':
animationParams['transform'] = animationParams['transform'] || {};
animationParams['transform'].translate = {
x: {
from: that.transformation.translateX || 0,
to: to.x || 0
},
y: {
from: that.transformation.translateY || 0,
to: to.y || 0
}
};
break;
case'arc':
case'points':
animationParams[name] = to;
break;
default:
animationParams[name] = {
from: that.settings[name] || 0,
to: to
}
}
});
that.renderer.animateElement(that, animationParams, $.extend({}, this.renderer.animOptions, options))
}
else {
if (params.translate) {
if ('x' in params.translate)
params.translateX = params.translate.x;
if ('y' in params.translate)
params.translateY = params.translate.y;
delete params.translate
}
if (options) {
options.step && options.step.call(that, 1, 1);
options.complete && options.complete.call(that)
}
this.applySettings(params)
}
},
stopAnimation: function(disableComplete) {
var that = this;
that.animation && that.animation.stop(true, disableComplete);
return that
},
move: function(x, y, animate, animOptions) {
x = x || 0,
y = y || 0;
animOptions = animOptions || {};
if (!animate)
this.applySettings({
translateX: x,
translateY: y
});
else
this.animate({translate: {
x: x,
y: y
}}, animOptions);
return this
},
rotate: function(angle, x, y, animate, animOptions) {
angle = angle || 0;
x = x || 0;
y = y || 0;
animOptions = animOptions || {};
if (!animate)
this.applySettings({rotate: [angle, x, y]});
else
this.animate({rotate: {
angle: angle,
x: x,
y: y
}}, animOptions)
},
remove: function() {
this.$element.remove()
},
_normalizeSettings: function(settings) {
var key,
style,
firstChar,
styleName,
prop,
value,
normalized = {},
fontSetting,
rtl = this.renderer.rtl;
for (key in settings) {
prop = key,
value = settings[prop];
if (prop === 'align') {
prop = 'text-anchor';
value = {
left: rtl ? 'end' : 'start',
center: 'middle',
right: rtl ? 'start' : 'end'
}[value]
}
else if (prop === 'font') {
style = this['_style'] = this['_style'] || {};
if (!$.isPlainObject(value))
continue;
$.each(value, function(fontSetting) {
switch (fontSetting) {
case'color':
styleName = 'fill';
break;
case'opacity':
styleName = 'fillOpacity';
break;
case'cursor':
styleName = fontSetting;
break;
default:
firstChar = fontSetting.charAt(0);
styleName = 'font' + fontSetting.replace(firstChar, firstChar.toUpperCase())
}
style[styleName] = value[fontSetting]
});
continue
}
else if (prop === 'dashStyle') {
prop = 'stroke-dasharray';
value = (value || 'none').toLowerCase();
if (value === 'solid' || value === 'none')
value = null;
else {
value = value.replace(/longdash/g, '8,3,').replace(/dash/g, '4,3,').replace(/dot/g, '1,3,').replace(/,$/, '').split(',');
value = $.map(value, function(p) {
return +p * (settings.strokeWidth || 1)
}).join(',')
}
}
else if (/^(linecap|linejoin)$/i.test(prop))
prop = 'stroke-' + prop;
else if (/^(translateX|translateY|rotate|scale)$/i.test(prop)) {
this['_' + prop] = value;
continue
}
else if (prop === 'clipId') {
prop = 'clip-path';
value = getPatternUrl(value, this.renderer.pathModified)
}
else if (prop === 'style') {
this['_style'] = this['_style'] || {};
$.extend(true, this['_style'], value);
continue
}
else if (prop === 'sharpEdges')
continue;
else if (prop === 'text')
continue;
else if (prop === 'segments')
continue;
else
prop = DX.inflector.dasherize(prop);
normalized[prop] = value
}
return this._applyTransformation(normalized)
},
_applyTransformation: function(settings) {
this.transformation = {
translateX: this._translateX,
translateY: this._translateY,
rotateAngle: 0,
rotateX: 0,
rotateY: 0
};
var tr = this.transformation,
rotate = this._rotate,
scale = this._scale,
transformations = [];
if (utils.isDefined(tr.translateX) || utils.isDefined(tr.translateY))
transformations.push('translate(' + (tr.translateX || 0) + ',' + (tr.translateY || 0) + ')');
if (utils.isDefined(rotate)) {
if (utils.isNumber(rotate)) {
tr.rotateAngle = rotate;
tr.rotateX = settings.x || 0;
tr.rotateY = settings.y || 0
}
else if ($.isArray(rotate)) {
tr.rotateAngle = rotate[0] || 0;
tr.rotateX = rotate[1] || 0;
tr.rotateY = rotate[2] || 0
}
else if (utils.isObject(rotate)) {
tr.rotateAngle = rotate.angle || 0;
tr.rotateX = rotate.x || 0;
tr.rotateY = rotate.y || 0
}
transformations.push('rotate(' + tr.rotateAngle + ',' + tr.rotateX + ',' + tr.rotateY + ')')
}
if (utils.isNumber(scale)) {
var value = utils.isDefined(scale) ? scale : 1;
transformations.push('scale(' + value + ',' + value + ')');
tr.scale = {
x: value,
y: value
}
}
else if (utils.isObject(scale)) {
var valueX = utils.isDefined(scale.x) ? scale.x : 1;
var valueY = utils.isDefined(scale.y) ? scale.y : 1;
transformations.push('scale(' + valueX + ',' + valueY + ')');
tr.scale = {
x: valueX,
y: valueY
}
}
if (transformations.length)
settings.transform = transformations.join(' ');
return settings
}
});
var RootSvgElement = BaseSvgElement.inherit({
defaultSettings: function() {
return {
width: 0,
height: 0,
style: {
'-webkit-tap-highlight-color': 'rgba(0, 0, 0, 0)',
display: 'block',
overflow: 'hidden'
},
xmlns: 'http://www.w3.org/2000/svg',
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
version: '1.1',
stroke: 'none',
strokeWidth: 0,
fill: 'none'
}
},
ctor: function(renderer, params) {
this.callBase(renderer, 'svg', params)
}
});
var RectSvgBaseElement = {
defaultSettings: function() {
return {
x: 0,
y: 0,
width: 0,
height: 0
}
},
adjustSettings: function() {
if (!utils.isDefined(this.settings.sharpEdges) || this.settings.sharpEdges) {
this.sharpEdges();
delete this.settings.sharpEdges
}
},
prepareSettings: function(settings) {
var prevStrokeWidth = this.settings ? Number(this.settings.strokeWidth) || 0 : 0,
newStrokeWidth,
maxStrokeWidth,
strokeWidthChanged = false;
if (utils.isDefined(settings.width))
this._realWidth = Number(settings.width);
if (utils.isDefined(settings.height))
this._realHeight = Number(settings.height);
if (utils.isDefined(settings.x))
this._realX = Number(settings.x);
if (utils.isDefined(settings.y))
this._realY = Number(settings.y);
if (utils.isDefined(settings.strokeWidth))
this._realStrokeWidth = Number(settings.strokeWidth);
this._realStrokeWidth = this._realStrokeWidth || this.defaultSettings().strokeWidth || 0;
maxStrokeWidth = ~~((this._realWidth < this._realHeight ? this._realWidth : this._realHeight) / 2);
newStrokeWidth = this._realStrokeWidth < maxStrokeWidth ? this._realStrokeWidth : maxStrokeWidth;
if (newStrokeWidth !== prevStrokeWidth) {
strokeWidthChanged = true;
settings.sharpEdges = true;
newStrokeWidth > 0 && (settings.strokeWidth = newStrokeWidth)
}
(utils.isDefined(settings.x) || strokeWidthChanged) && (settings.x = this._realX + newStrokeWidth / 2);
(utils.isDefined(settings.y) || strokeWidthChanged) && (settings.y = this._realY + newStrokeWidth / 2);
(utils.isDefined(settings.width) || strokeWidthChanged) && (settings.width = this._realWidth - newStrokeWidth);
(utils.isDefined(settings.height) || strokeWidthChanged) && (settings.height = this._realHeight - newStrokeWidth)
},
applySettings: function(settings) {
var settings = $.extend(true, {}, settings);
this.prepareSettings(settings);
return this.callBase(settings)
},
sharpEdges: function() {
var strokeWidth = Math.round(this.settings.strokeWidth || 0),
correction = strokeWidth % 2 / 2;
this.settings.x = Math.floor(this.settings.x - correction || 0) + correction;
this.settings.y = Math.floor(this.settings.y - correction || 0) + correction;
this.settings.width = Math.floor(this.settings.width || 0);
this.settings.height = Math.floor(this.settings.height || 0);
this.settings.strokeWidth > 0 && (this.settings.strokeWidth = strokeWidth)
}
};
var ImageSvgElement = BaseSvgElement.inherit(RectSvgBaseElement).inherit({
ctor: function(renderer, params, href, location) {
var locationToPreserveAspectRatioMap = {
full: 'none',
lefttop: 'xMinYMin',
leftcenter: 'xMinYMid',
leftbottom: 'xMinYMax',
centertop: 'xMidYMin',
center: 'xMidYMid',
centerbottom: 'xMidYMax',
righttop: 'xMaxYMin',
rightcenter: 'xMaxYMid',
rightbottom: 'xMaxYMax'
};
this.href = utils.isDefined(href) ? href : '';
this.preserveAspectRatio = locationToPreserveAspectRatioMap[(location || '').toLowerCase()];
this.preserveAspectRatio = this.preserveAspectRatio || 'none';
this.callBase(renderer, 'image', params)
},
adjustSettings: function() {
this.callBase();
this.element.setAttributeNS('http://www.w3.org/1999/xlink', 'href', this.href);
if (this.preserveAspectRatio)
this.element.setAttribute('preserveAspectRatio', this.preserveAspectRatio)
}
});
var RectSvgElement = BaseSvgElement.inherit(RectSvgBaseElement).inherit({
defaultSettings: function() {
return {
x: 0,
y: 0,
width: 0,
height: 0,
rx: 0,
ry: 0
}
},
ctor: function(renderer, params) {
this.callBase(renderer, 'rect', params)
}
});
var PathSvgElement = BaseSvgElement.inherit({
defaultSettings: function() {
return {points: {
x: 0,
y: 0
}}
},
getNodeName: function() {
return 'path'
},
getPathAttributeName: function() {
return 'd'
},
ctor: function(renderer, params) {
this.callBase(renderer, this.getNodeName(), params)
},
dispose: function() {
this.segments = null;
this.fromSegments = null;
this.callBase()
},
adjustSettings: function() {
this.prepareSegments(this.settings)
},
applySettings: function(settings) {
var settings = settings || {};
if (this.settings && settings.strokeWidth && this.settings.strokeWidth !== settings.strokeWidth)
settings.sharpEdges = true;
return this.callBase(settings)
},
prepareSegments: function(params) {
if ('points' in params) {
var points = params.points,
firstElem = points[0],
close = this.closePath || params.closePath,
segments = [],
i;
if (utils.isObject(firstElem))
segments = $.map(points, function(pt, i) {
if (!pt)
return null;
if (!i)
return [['M', pt.x, pt.y]];
return [['L', pt.x, pt.y]]
});
else if (utils.isNumber(firstElem))
for (i = 0; i < points.length; i += 2) {
if (!i) {
segments = [['M', points[i] || 0, points[i + 1] || 0]];
continue
}
segments.push(['L', points[i] || 0, points[i + 1] || 0])
}
else
segments = [['M', 0, 0]];
if (close)
segments.push(['Z']);
this.segments = segments;
delete params.points;
delete params.closePath;
params.sharpEdges = true
}
if (params.sharpEdges) {
this.sharpEdges();
this.combinePathParams(params);
delete params.sharpEdges
}
},
customizeSegments: function(segments) {
return segments
},
combinePathParams: function(params) {
var path;
this.segments = this.customizeSegments(this.segments);
if (this.segments) {
path = $.map(this.segments, function(seg, i) {
return seg.join(' ')
});
path = path.join(' ');
params[this.getPathAttributeName()] = path
}
},
_prepareDifferrentPath: function(from, to) {
var end = {},
constsSeg;
if (to.length > from.length)
this._makeEqualPath(from, to);
else {
this.combinePathParams(end);
this._makeEqualPath(to, from)
}
return end.d
},
_prepareConstSegment: function(seg) {
seg[0] = "L"
},
_makeEqualPath: function(short, long) {
var constSeg = short[short.length - 1].slice();
this._prepareConstSegment(constSeg);
for (var i = short.length; i < long.length; i++)
short[i] = constSeg
},
animate: function(params, options, complete) {
var that = this;
if (!('points' in params) || !that.renderer.animOptions.enabled)
return that.callBase(params, options, complete);
var fromPath = that.segments,
end;
that.prepareSegments(params);
delete params.d;
if (fromPath.length === that.segments.length)
params.points = {
from: fromPath,
to: that.segments
};
else
end = that._prepareDifferrentPath(fromPath, that.segments);
params.points = {
from: fromPath,
to: that.segments,
end: end
};
that.callBase(params, options, complete)
},
sharpEdges: function() {
var that = this,
segLength = that.segments.length,
i = 0,
curSeg,
nextSeg,
curX,
curY,
nextX,
nextY,
curXIdx,
curYIdx,
nextXIdx,
nextYIdx,
strokeWidth = Math.round(that.settings.strokeWidth || 0),
correction = strokeWidth % 2 / 2;
for (i; i < segLength - 1; i++) {
curSeg = that.segments[i];
nextSeg = that.segments[i + 1];
if (nextSeg[0] === 'Z' && i)
nextSeg = that.segments[0];
switch (curSeg[0]) {
case'M':
case'L':
curXIdx = 1;
curYIdx = 2;
break;
case'C':
curXIdx = 5;
curYIdx = 6;
break;
case'A':
curXIdx = 6;
curYIdx = 7;
break;
case'Z':
continue
}
switch (nextSeg[0]) {
case'M':
case'L':
nextXIdx = 1;
nextYIdx = 2;
break;
case'C':
nextXIdx = 5;
nextYIdx = 6;
break;
case'A':
nextXIdx = 6;
nextYIdx = 7;
break;
case'Z':
continue
}
curX = Math.floor(curSeg[curXIdx]);
curY = Math.floor(curSeg[curYIdx]);
nextX = nextSeg[nextXIdx] = Math.floor(nextSeg[nextXIdx]);
nextY = nextSeg[nextYIdx] = Math.floor(nextSeg[nextYIdx]);
curSeg[curXIdx] = i == 0 ? curX : curSeg[curXIdx];
curSeg[curYIdx] = i == 0 ? curY : curSeg[curYIdx];
if (curX == nextX) {
curSeg[curXIdx] = curX + correction;
nextSeg[nextXIdx] = nextX + correction
}
if (curY == nextY) {
curSeg[curYIdx] = curY + correction;
nextSeg[nextYIdx] = nextY + correction
}
}
}
});
var SegmentRectSvgElement = PathSvgElement.inherit(RectSvgBaseElement).inherit({
defaultSettings: function() {
return $.extend(true, {}, this.callBase(), {segments: {
top: true,
bottom: true,
left: true,
right: true
}})
},
prepareSegments: function() {
var that = this,
settings = that.settings,
left = settings.x,
right = left + settings.width,
top = settings.y,
bottom = top + settings.height,
segments = [],
segmentSequence,
visiblyOpt = 0,
prevSegmentVisibility = 0;
var allSegment = {
top: [['M', left, top], ['L', right, top]],
right: [['M', right, top], ['L', right, bottom]],
bottom: [['M', right, bottom], ['L', left, bottom]],
left: [['M', left, bottom], ['L', left, top]]
};
$.each(allSegment, function(seg, _) {
var visibility = !!that.settings.segments[seg];
visiblyOpt = visiblyOpt * 2 + ~~visibility
});
switch (visiblyOpt) {
case(13):
case(9):
segmentSequence = ['left', 'top', 'right', 'bottom'];
break;
case(11):
segmentSequence = ['bottom', 'left', 'top', 'right'];
break;
default:
segmentSequence = ['top', 'right', 'bottom', 'left']
}
$.each(segmentSequence, function(_, seg) {
var segmentVisibility = !!that.settings.segments[seg];
if (segmentVisibility)
$.each(allSegment[seg].slice(prevSegmentVisibility), function(_, segment) {
segments.push(segment)
});
prevSegmentVisibility = ~~segmentVisibility
});
visiblyOpt == 15 && segments.push(['Z']);
this.segments = segments.length ? segments : [['M', 0, 0], ['Z']];
this.combinePathParams(settings)
},
adjustSettings: function() {
this.callBase();
this.prepareSegments()
},
applySettings: function(settings) {
var segments = this.settings && this.settings.segments || this.defaultSettings().segments;
settings.segments = $.extend(true, {}, segments || {}, settings.segments);
return this.callBase(settings)
}
});
var baseAreaElement = {
defaultSettings: function() {
return {points: {
x: 0,
y: 0
}}
},
ctor: function(renderer, params) {
this.closePath = true;
this.callBase(renderer, params)
},
_tailIndex: 0,
_makeEqualPath: function(short, long) {
var i,
tail,
head,
constsSeg1,
constsSeg2,
newTail = [];
if ((short.length - 1) % 2 == 0 && (long.length - 1) % 2 == 0) {
i = (short.length - 1) / 2 - 1;
tail = short.slice(i + 1);
head = short.slice(0, i + 1);
constsSeg1 = head[head.length - 1];
constsSeg2 = tail[this._tailIndex];
this._prepareConstSegment(constsSeg1);
for (var j = i; j < (long.length - 1) / 2 - 1; j++) {
head.push(constsSeg1);
newTail.push(constsSeg2)
}
head = this._concatAnimationSegment(head, newTail, tail);
for (i = 0; i < head.length; i++)
short[i] = head[i]
}
},
_concatAnimationSegment: function(head, newTail, tail) {
return head.concat(newTail, tail)
}
};
var AreaSvgElement = PathSvgElement.inherit(baseAreaElement);
var BezierSvgElement = PathSvgElement.inherit({
defaultSettings: function() {
return {points: {
x: 0,
y: 0
}}
},
_prepareConstSegment: function(seg) {
var x = seg[seg.length - 2],
y = seg[seg.length - 1];
seg[0] = "C";
seg[5] = seg[3] = seg[1] = x;
seg[6] = seg[4] = seg[2] = y
},
prepareSegments: function(params) {
if (!('points' in params))
return;
var points = params.points,
firstElem = points[0],
close = this.closePath || params.closePath,
segments = [],
seg = [],
i,
x,
y;
var cnt = 0;
if (utils.isObject(firstElem)) {
for (i = 0; i < points.length; i++) {
x = points[i].x;
y = points[i].y;
if (!i) {
segments = [['M', x, y]];
continue
}
if ((i - 1) % 3 == 0) {
if (seg.length > 0)
segments.push(seg);
seg = ['C', x, y];
continue
}
seg.push(x);
seg.push(y)
}
if (seg.length > 0)
segments.push(seg)
}
else if (utils.isNumber(firstElem)) {
for (i = 0; i < points.length; i += 2) {
x = points[i];
y = points[i + 1];
if (!i) {
segments = [['M', x, y || 0]];
continue
}
if ((i - 2) % 6 == 0) {
if (seg.length > 0)
segments.push(seg);
seg = ['C', x, y || 0];
continue
}
seg.push(x);
seg.push(y || 0)
}
if (seg.length > 0)
segments.push(seg)
}
else
segments = [['M', 0, 0]];
if (close)
segments.push(['Z']);
this.segments = segments;
delete params.points;
delete params.closePath;
this.combinePathParams(params)
}
});
var BezierAreaSvgElement = BezierSvgElement.inherit(baseAreaElement).inherit({
_concatAnimationSegment: function(head, newTail, tail) {
var point = tail.splice(0, 1);
return head.concat(point.concat(newTail), tail)
},
_tailIndex: 1
});
var ArcSvgElement = PathSvgElement.inherit({
defaultSettings: function() {
return {
x: 0,
y: 0,
linejoin: 'round'
}
},
createArcSegments: function(x, y, innerR, outerR, startAngle, endAngle, isCircle) {
var longFlag = Math.floor(Math.abs(endAngle - startAngle) / Math.PI) % 2 ? '1' : '0',
xOuterStart = x + outerR * Math.cos(startAngle),
yOuterStart = y - outerR * Math.sin(startAngle),
xOuterEnd = x + outerR * Math.cos(endAngle),
yOuterEnd = y - outerR * Math.sin(endAngle),
xInnerStart = x + innerR * Math.cos(endAngle),
yInnerStart = y - innerR * Math.sin(endAngle),
xInnerEnd = x + innerR * Math.cos(startAngle),
yInnerEnd = y - innerR * Math.sin(startAngle);
return [['M', xOuterStart, yOuterStart], ['A', outerR, outerR, 0, longFlag, 0, xOuterEnd, yOuterEnd], [isCircle ? 'M' : 'L', xInnerStart, yInnerStart], ['A', innerR, innerR, 0, longFlag, 1, xInnerEnd, yInnerEnd], ['Z']]
},
prepareSegments: function(params) {
if (!('x' in params) && !('y' in params) && !('outerRadius' in params) && !('innerRadius' in params) && !('startAngle' in params) && !('endAngle' in params))
return;
var x = utils.isNumber(params.x) ? Number(params.x) : 0,
y = utils.isNumber(params.y) ? Number(params.y) : 0,
outerR = utils.isNumber(params.outerRadius) ? Number(params.outerRadius) : 0,
innerR = utils.isNumber(params.innerRadius) ? Number(params.innerRadius) : 0,
startAngle = utils.isNumber(params.startAngle) ? Number(params.startAngle) : 0,
endAngle = utils.isNumber(params.endAngle) ? Number(params.endAngle) : 360,
isCircle;
this.segments = [['M', 0, 0], ['Z']];
if (outerR || innerR) {
var tmp = Math.min(outerR, innerR);
outerR = Math.max(outerR, innerR);
innerR = tmp;
if (Math.round(startAngle) != Math.round(endAngle)) {
if (Math.abs(endAngle - startAngle) % 360 == 0) {
startAngle = 0;
endAngle = 360;
isCircle = true;
endAngle -= 0.0001
}
if (startAngle > 360)
startAngle = startAngle % 360;
if (endAngle > 360)
endAngle = endAngle % 360;
if (startAngle > endAngle)
startAngle -= 360;
startAngle = startAngle * Math.PI / 180;
endAngle = endAngle * Math.PI / 180;
this.segments = this.createArcSegments(x, y, innerR, outerR, startAngle, endAngle, isCircle)
}
}
this.x = params.x;
this.y = params.y;
this.outerRadius = params.outerRadius;
this.innerRadius = params.innerRadius;
this.startAngle = params.startAngle;
this.endAngle = params.endAngle;
delete params.x;
delete params.y;
delete params.outerRadius;
delete params.innerRadius;
delete params.startAngle;
delete params.endAngle;
this.combinePathParams(params)
},
animate: function(params) {
var _this = this;
if ('x' in params && 'y' in params && 'outerRadius' in params && 'innerRadius' in params && 'startAngle' in params && 'endAngle' in params && this.renderer.animOptions.enabled) {
var settings = this.settings;
params.arc = {
from: {
x: this.x,
y: this.y,
outerRadius: this.outerRadius,
innerRadius: this.innerRadius,
startAngle: this.startAngle,
endAngle: this.endAngle
},
to: {
x: params.x,
y: params.y,
outerRadius: params.outerRadius,
innerRadius: params.innerRadius,
startAngle: params.startAngle,
endAngle: params.endAngle
}
};
delete params.d;
delete params.x;
delete params.y;
delete params.outerRadius;
delete params.innerRadius;
delete params.startAngle;
delete params.endAngle
}
this.callBase.apply(this, arguments)
}
});
var CircleSvgElement = BaseSvgElement.inherit({
defaultSettings: function() {
return {
cx: 0,
cy: 0,
r: 0
}
},
ctor: function(renderer, params) {
this.callBase(renderer, 'circle', params)
}
});
var TextSvgElement = BaseSvgElement.inherit({
defaultSettings: function() {
return {
x: 0,
y: 0
}
},
ctor: function(renderer, params) {
this.tspans = [];
this.callBase(renderer, 'text', params)
},
dispose: function() {
this.tspans = null;
this.callBase()
},
updateText: function(text) {
if (!utils.isDefined(text))
text = '';
this.applySettings({text: text})
},
adjustSettings: function() {
if (!('text' in this.settings)) {
this.changeX();
return
}
this._createElementWithText(this.settings.text)
},
changeX: function() {
for (var i = 0; i < this.tspans.length; i++)
if (this.tspans[i].settings.x != undefined)
this.tspans[i].applySettings({x: this.settings.x})
},
_createElementWithText: function(text) {
var div,
i;
this.clear();
text = text.toString().replace(/\r/g, "");
text = text.replace(/\n/g, "
");
div = doc.createElement("div");
div.innerHTML = text;
div.params = {style: {}};
this._orderText(div)
},
clear: function() {
this.callBase();
this.tspans = []
},
_orderText: function(node) {
var textArray = [],
defaultFontSize = (this.settings.font ? this.settings.font.size : 12) || 12;
var order = function(strCount, node, textArray) {
var params = {style: {}},
textArray = textArray || [];
node.params = node.params || {};
if (node.parentNode && node.nodeName != "#text")
if (node.parentNode.params)
for (var i in node.parentNode.params)
node.params[i] = node.parentNode.params[i];
switch (node.tagName) {
case"B" || "STRONG":
node.params.fontWeight = "bold";
break;
case"I" || "EM":
node.params.fontStyle = "italic";
break;
case"U":
node.params.textDecoration = "underline";
break;
case"BR":
strCount++;
break
}
if (node.style) {
if (node.style.fontSize)
node.params.fontSize = (parseInt(node.style.fontSize) || node.params.fontSize) + "px";
node.params.fill = node.style.color || node.params.fill;
node.params.fontStyle = node.style.fontStyle || node.params.fontStyle;
node.params.fontWeight = node.style.fontWeight || node.params.fontWeight;
node.params.textDecoration = node.style.textDecoration || node.params.textDecoration
}
var childnum = node.childNodes.length;
var count = 0;
while (count != childnum)
strCount = order(strCount, node.childNodes[count++], textArray);
if (node.wholeText != undefined) {
params.fill = node.parentNode.params.fill;
params.text = node.wholeText;
node.parentNode.params.fontSize && (params.style.fontSize = node.parentNode.params.fontSize);
node.parentNode.params.fontStyle && (params.style.fontStyle = node.parentNode.params.fontStyle);
node.parentNode.params.fontWeight && (params.style.fontWeight = node.parentNode.params.fontWeight);
node.parentNode.params.textDecoration && (params.style.textDecoration = node.parentNode.params.textDecoration);
textArray.push({
params: params,
line: strCount
})
}
return strCount
};
order(0, node, textArray);
for (var txt = 0; txt < textArray.length; txt++) {
if (txt != 0)
if (textArray[txt].line != textArray[txt - 1].line) {
textArray[txt].params.dy = textArray[txt].params.style.fontSize || defaultFontSize;
textArray[txt].params.x = this.settings.x
}
else {
textArray[txt].params.dy = 0;
textArray[txt].params.dx = 0
}
else {
textArray[txt].params.x = this.settings.x;
textArray[txt].params.dy = 0
}
var tspan = new TspanSvgElement(this.renderer, textArray[txt].params);
tspan.append(this);
this.tspans.push(tspan)
}
}
});
var TspanSvgElement = BaseSvgElement.inherit({ctor: function(renderer, params) {
var text = params.text || '';
delete params.text;
this.callBase(renderer, 'tspan', params);
this.element.appendChild(doc.createTextNode(text))
}});
var GroupSvgElement = BaseSvgElement.inherit({
ctor: function(renderer, params) {
this.callBase(renderer, 'g', params)
},
update: $.noop
});
var PatternSvgElement = BaseSvgElement.inherit({
ctor: function(renderer, params) {
this.__patternParams = $.extend({}, params);
var id = utils.getNextDefsSvgId(),
color = params.color,
hatching = params.hatching,
opacity = hatching.opacity,
width = hatching.width || 1,
step = hatching.step || 6,
direction = hatching.direction,
options = {
strokeWidth: width,
stroke: color
};
this.callBase(renderer, 'pattern', {
id: id,
width: step,
height: step
});
this.element.setAttribute('patternUnits', 'userSpaceOnUse');
this._rect = renderer.createRect(0, 0, step, step, 0, {
fill: color,
opacity: opacity
}).append(this);
this._path = renderer.createPath(0, options).append(this);
if (direction === 'right')
this._path.applySettings({d: "M " + step / 2 + " " + -step / 2 + " L " + -step / 2 + " " + step / 2 + "M 0 " + step + " L " + step + " 0 M " + step * 1.5 + " " + step / 2 + " L " + step / 2 + " " + step * 1.5});
else if (direction === 'left')
this._path.applySettings({d: "M 0 0 L " + step + ' ' + step + " M " + -step / 2 + " " + step / 2 + " L " + step / 2 + " " + step * 1.5 + " M " + step / 2 + -step / 2 + " L " + step * 1.5 + " " + step / 2});
this.id = getPatternUrl(id, renderer.pathModified)
},
append: function() {
return this.callBase(this.renderer.getDefsSvg())
},
clear: function() {
this.callBase();
this._path = null
},
dispose: function() {
this._path = null;
this.callBase()
}
});
var ClipRectSvgElement = BaseSvgElement.inherit({
ctor: function(renderer, params) {
this.__clipRectParams = $.extend({}, params);
var x = params.x,
y = params.y,
w = params.w,
h = params.h,
id = utils.getNextDefsSvgId();
delete params.x;
delete params.y;
delete params.w;
delete params.h;
this.callBase(renderer, 'clipPath', {id: id});
this.id = id;
this._rect = renderer.createRect(x, y, w, h, 0, params);
this._rect.append(this)
},
append: function() {
return this.callBase(this.renderer.getDefsSvg())
},
updateRectangle: function(settings) {
this._rect.applySettings(settings)
},
dispose: function() {
this._rect = null;
this.callBase()
}
});
var BaseFilterSvgElement = BaseSvgElement.inherit({
ctor: function(renderer) {
this.applySettings = $.noop;
this.callBase(renderer, 'filter');
delete this.applySettings;
this.ref = null;
this._create()
},
append: function() {
return this.callBase(this.renderer.getDefsSvg())
},
dispose: function() {
while (this.element.firstChild)
this.element.removeChild(this.element.firstChild);
this.callBase();
return this
},
applySettings: function(settings) {
settings = settings || {};
settings.id = utils.getNextDefsSvgId();
this.$element.attr({
id: settings.id,
x: settings.x || null,
y: settings.y || null,
width: settings.width || null,
height: settings.height || null
});
this.ref = settings.id ? getPatternUrl(settings.id, this.renderer.pathModified) : null;
this._update(settings);
return this
}
});
function setAttributes(element, attr) {
$.each(attr, function(name, value) {
element.setAttribute(name, value)
})
}
var ShadowFilterSvgElement = BaseFilterSvgElement.inherit({
_create: function() {
var that = this,
gaussianBlur = that._gaussianBlur = createElement('feGaussianBlur'),
offset = that._offset = createElement('feOffset'),
flood = that._flood = createElement('feFlood'),
composite = that._composite = createElement('feComposite'),
finalComposite = createElement('feComposite');
setAttributes(gaussianBlur, {
'in': 'SourceGraphic',
result: 'gaussianBlurResult'
});
setAttributes(offset, {
'in': 'gaussianBlurResult',
result: 'offsetResult'
});
setAttributes(flood, {result: 'floodResult'});
setAttributes(composite, {
'in': 'floodResult',
in2: 'offsetResult',
operator: 'in',
result: 'compositeResult'
});
setAttributes(finalComposite, {
'in': 'SourceGraphic',
in2: 'compositeResult',
operator: 'over'
});
that.element.appendChild(gaussianBlur);
that.element.appendChild(offset);
that.element.appendChild(flood);
that.element.appendChild(composite);
that.element.appendChild(finalComposite)
},
_update: function(settings) {
setAttributes(this._gaussianBlur, {stdDeviation: settings.blur || 0});
setAttributes(this._offset, {
dx: settings.dx || 0,
dy: settings.dy || 0
});
setAttributes(this._flood, {
'flood-color': settings.color,
'flood-opacity': settings.opacity
})
}
});
renderers.SvgRenderer = Class.inherit({
ctor: function(options) {
var that = this;
options = options || {};
that._setAnimationOptions(options.animation || {});
that.animationController = new renderers.AnimationController;
that.pathModified = options.pathModified;
that.rtl = !!options.rtl;
that.cssClass = options.cssClass || '';
that.recreateCanvas(options.width, options.height)
},
dispose: function() {
var that = this;
that.detachContainer();
that.svgRoot && (that.svgRoot.remove(), that.svgRoot = null);
that.animationController.dispose();
that.animOptions = null;
that.animationController = null
},
_setAnimationOptions: function(options) {
this.animOptions = {
enabled: true,
duration: 1000,
easing: 'easeOutCubic'
};
if ('enabled' in options)
this.animOptions.enabled = options.enabled;
if ('duration' in options)
this.animOptions.duration = options.duration;
if ('easing' in options)
this.animOptions.easing = options.easing
},
animationEnabled: function() {
return !!this.animOptions.enabled
},
updateAnimationOptions: function(newOptions) {
this._setAnimationOptions($.extend(this.animOptions || {}, newOptions))
},
stopAllAnimations: function(lock) {
lock ? this.animationController.lock() : this.animationController.stop()
},
detachContainer: function() {
var that = this;
that.svgRoot && that.svgRoot.detach();
that.defsSvg && (that.defsSvg.remove(), that.defsSvg = null);
that.drawn = null
},
recreateCanvas: function(width, height, cssClass) {
if (width >= 0 && height >= 0) {
if (!this.svgRoot) {
this.cssClass = cssClass || this.cssClass;
this.svgRoot = new RootSvgElement(this, {
width: width,
height: height,
'class': this.cssClass,
direction: this.rtl ? 'rtl' : 'ltr'
});
this.animationController.element = this.svgRoot.element
}
else
this.svgRoot.applySettings({
width: width,
height: height
});
this.defsSvg && this.defsSvg.clear("pattern")
}
},
resize: function(width, height) {
var root = this.getRoot();
root && width > 0 && height > 0 && root.applySettings({
width: width,
height: height
})
},
getRoot: function() {
return this.svgRoot
},
isInitialized: function() {
return !!this.svgRoot
},
draw: function(container) {
if (!container || this.drawn)
return;
container.appendChild(this.getRoot().element);
this.drawn = true
},
updateParams: function(params, options) {
if (options && options.strokeWidth)
params.strokeWidth = options.strokeWidth
},
animateElement: function(element, params, options) {
this.animationController.animateElement(element, params, options)
},
createRect: function(x, y, w, h, r, options) {
var params = {
x: x,
y: y,
width: w,
height: h,
rx: r,
ry: r
};
if (options && !options.inh)
$.extend(params, options);
this.updateParams(params, options);
return new RectSvgElement(this, params)
},
createSegmentRect: function(x, y, w, h, r, segments, options) {
var params = $.extend({}, options || {}, {
x: x,
y: y,
width: w,
height: h,
rx: r,
ry: r,
segments: segments
});
return new SegmentRectSvgElement(this, params)
},
createClipRect: function(x, y, w, h) {
var attr = {
x: x,
y: y,
w: w,
h: h,
fill: 'none',
stroke: 'none',
strokeWidth: 0
};
return new ClipRectSvgElement(this, attr)
},
createPattern: function(color, hatching) {
hatching = hatching || {};
hatching.direction = (hatching.direction || '').toLowerCase();
if (hatching.direction !== 'right' && hatching.direction !== 'left')
return {
id: color,
append: function() {
return this
},
clear: function(){},
dispose: function(){}
};
return new PatternSvgElement(this, {
hatching: hatching,
color: color
})
},
createImage: function(x, y, w, h, href, options) {
var params = $.extend({}, options || {}, {
x: x,
y: y,
width: w,
height: h
});
return new ImageSvgElement(this, params, href, params.location)
},
createLine: function(x1, y1, x2, y2, options) {
var params = {points: [x1, y1, x2, y2]};
if (options && !options.inh)
$.extend(params, options);
this.updateParams(params, options);
return new PathSvgElement(this, params)
},
createPath: function(points, options) {
var params = {points: points};
if (options && !options.inh)
$.extend(params, options);
this.updateParams(params, options);
return new PathSvgElement(this, params)
},
createSimplePath: function(options) {
return new BaseSvgElement(this, 'path', options)
},
createBezierPath: function(points, options) {
var params = {points: points};
if (options && !options.inh)
$.extend(params, options);
this.updateParams(params, options);
return new BezierSvgElement(this, params)
},
createArea: function(points, options) {
var params = {points: points};
if (options && !options.inh)
$.extend(params, options);
this.updateParams(params, options);
return new AreaSvgElement(this, params)
},
createBezierArea: function(points, options) {
var params = {points: points};
if (options && !options.inh)
$.extend(params, options);
this.updateParams(params, options);
return new BezierAreaSvgElement(this, params)
},
createCircle: function(x, y, r, options) {
var params = {
cx: x,
cy: y,
r: r
};
if (options && !options.inh)
$.extend(params, options);
return new CircleSvgElement(this, params)
},
createArc: function(x, y, outerRadius, innerRadius, startAngle, endAngle, options) {
var params = {
x: x,
y: y,
outerRadius: outerRadius,
innerRadius: innerRadius,
startAngle: startAngle,
endAngle: endAngle
};
if (options && !options.inh)
$.extend(params, options);
this.updateParams(params, options);
return new ArcSvgElement(this, params)
},
createText: function(text, x, y, options) {
var params = {
x: x,
y: y,
text: text
};
if (options && !options.inh)
$.extend(params, options);
return new TextSvgElement(this, params)
},
createGroup: function(options) {
return new GroupSvgElement(this, options)
},
createFilter: function(type) {
var filterType = type === 'shadow' ? ShadowFilterSvgElement : null;
if (filterType)
return new filterType(this);
return null
},
getDefsSvg: function() {
this.defsSvg = this.defsSvg || new BaseSvgElement(this, 'defs').append();
return this.defsSvg
},
svg: function() {
return this.svgRoot.$element.parent().html()
}
});
function buildPath(points) {
var i = 0,
ii = points.length,
list = [];
for (; i < ii; )
list.push('L', points[i++].toFixed(2), points[i++].toFixed(2));
if (ii) {
list[0] = 'M';
list.push('Z');
list = list.join(' ')
}
else
list = '';
return list
}
function processCircleSettings(x, y, size, borderWidth) {
var correct = size + ~~borderWidth & 1;
return {
cx: correct ? x + 0.5 : x,
cy: correct ? y + 0.5 : y,
r: size / 2
}
}
renderers._svgBuildPath = buildPath;
renderers._svgProcessCircleSettings = processCircleSettings;
renderers._svgRendererInternals = {
BaseSvgElement: BaseSvgElement,
RootSvgElement: RootSvgElement,
RectSvgElement: RectSvgElement,
ImageSvgElement: ImageSvgElement,
PathSvgElement: PathSvgElement,
AreaSvgElement: AreaSvgElement,
BezierSvgElement: BezierSvgElement,
BezierAreaSvgElement: BezierAreaSvgElement,
CircleSvgElement: CircleSvgElement,
TextSvgElement: TextSvgElement,
TspanSvgElement: TspanSvgElement,
GroupSvgElement: GroupSvgElement,
ArcSvgElement: ArcSvgElement,
RectSvgBaseElement: RectSvgBaseElement,
SegmentRectSvgElement: SegmentRectSvgElement,
ClipRectSvgElement: ClipRectSvgElement,
PatternSvgElement: PatternSvgElement,
ShadowFilterSvgElement: ShadowFilterSvgElement
}
})(jQuery, DevExpress);
/*! Module viz-core, file vmlRenderer.js */
(function($, DX) {
var renderers = DX.viz.renderers,
utils = DX.utils,
doc = document,
svgRendererInternals = renderers._svgRendererInternals,
documentFragment = doc.createDocumentFragment();
function createVmlElement(nodeName) {
var element = doc.createElement(nodeName);
return documentFragment.appendChild(element)
}
var appendTimerID;
var vmlElementsToAppend = [];
var CSS_PROPERTIES = ['position', 'display', 'visibility', 'filter', 'margin', 'marginTop', 'marginLeft', 'marginRight', 'marginBottom', 'whiteSpace', 'clip', 'overflow'];
var INHERITABLE_PROPERTIES = ['stroke', 'fill', 'opacity', 'strokeWidth', 'align', 'dashStyle'];
var defaultVmlSettings = {
x: 0,
y: 0,
width: 1,
height: 1,
position: 'absolute',
behavior: 'url(#default#VML)',
display: 'inline-block',
xmlns: "urn:schemas-microsoft-com:vml"
};
var CLIP_RECT_CLASS = "dx-vml-clip-rect";
var extendDefaultVmlOptions = function(customOptions, baseOptions) {
return $.extend(true, baseOptions || {}, defaultVmlSettings, customOptions)
};
var parseRotateParameter = function(rotate, defaultX, defaultY) {
var rotateObject;
if (utils.isDefined(rotate))
if (utils.isNumber(rotate))
rotateObject = {
angle: rotate,
x: defaultX || 0,
y: defaultY || 0
};
else if ($.isArray(rotate))
rotateObject = {
angle: rotate[0] || 0,
x: rotate[1] || 0,
y: rotate[2] || 0
};
else if (utils.isObject(rotate))
rotateObject = {
angle: rotate.angle || 0,
x: rotate.x || 0,
y: rotate.y || 0
};
return rotateObject
};
function adjustOpacity(value) {
return value >= 0.002 ? value : value === null ? 1 : 0.002
}
var applySubElementAttribute = function(vmlElement, params, name) {
var element = vmlElement.element,
subElement,
value = params[name];
if (name === 'opacity' || name === 'fillOpacity')
if (element.fill)
element.fill.opacity = adjustOpacity(value);
if (name === 'joinStyle')
if (element.stroke)
element.stroke.joinStyle = value;
if (name === 'opacity' || name === 'strokeOpacity')
if (element.stroke)
element.stroke.opacity = value >= 0.002 ? value : value === null ? 1 : 0.002;
if (name === 'dashstyle')
if (element.stroke)
element.stroke.dashstyle = value
};
var getBoundingClientRect = function(element) {
var i,
resultRect,
rect,
tagName = element.tagName.toLowerCase(),
points,
value,
halfStrokeWidth;
if (element.className && element.className.indexOf(CLIP_RECT_CLASS) !== -1)
return;
if (tagName === 'div') {
if (element.childNodes.length > 0) {
resultRect = {};
for (i = 0; i < element.childNodes.length; i++) {
rect = getBoundingClientRect(element.childNodes[i]);
if (!rect)
continue;
resultRect.left = resultRect.left === undefined || rect.left < resultRect.left ? rect.left : resultRect.left;
resultRect.top = resultRect.top === undefined || rect.top < resultRect.top ? rect.top : resultRect.top;
resultRect.right = resultRect.right === undefined || rect.right > resultRect.right ? rect.right : resultRect.right;
resultRect.bottom = resultRect.bottom === undefined || rect.bottom > resultRect.bottom ? rect.bottom : resultRect.bottom
}
}
}
else if (tagName === 'shape' || tagName === 'vml:shape') {
points = (element.path.value || element.path).match(/[-0-9]+/g);
resultRect = {};
rect = element.getBoundingClientRect();
for (i = 0; i < points.length; i++) {
value = parseInt(points[i]);
if (i % 2) {
resultRect.top = resultRect.top === undefined || value < resultRect.top ? value : resultRect.top;
resultRect.bottom = resultRect.bottom === undefined || value > resultRect.bottom ? value : resultRect.bottom
}
else {
resultRect.left = resultRect.left === undefined || value < resultRect.left ? value : resultRect.left;
resultRect.right = resultRect.right === undefined || value > resultRect.right ? value : resultRect.right
}
}
resultRect.left = resultRect.left || 0;
resultRect.top = resultRect.top || 0;
resultRect.right = resultRect.right || 0;
resultRect.bottom = resultRect.bottom || 0;
if (rect.right - rect.left <= 1 && rect.top - rect.bottom <= 1) {
resultRect.right = resultRect.right + rect.left;
resultRect.bottom = resultRect.bottom + rect.top;
resultRect.left = resultRect.left + rect.left;
resultRect.top = resultRect.top + rect.top
}
else {
resultRect.right = resultRect.right - resultRect.left + rect.left;
resultRect.bottom = resultRect.bottom - resultRect.top + rect.top;
resultRect.left = rect.left;
resultRect.top = rect.top
}
halfStrokeWidth = Math.ceil(parseFloat(element.strokeweight) / 2);
if (halfStrokeWidth && halfStrokeWidth > 1) {
resultRect.left -= halfStrokeWidth;
resultRect.top -= halfStrokeWidth;
resultRect.right += halfStrokeWidth;
resultRect.bottom += halfStrokeWidth
}
}
else
resultRect = element.getBoundingClientRect();
return resultRect
};
var BaseVmlElement = {
isVml: function() {
return true
},
dispose: function() {
this.childElements = null;
this._style = null;
this._fullSettings = null;
this.callBase()
},
defaultSettings: function(customOptions) {
return extendDefaultVmlOptions(customOptions, this.callBase ? this.callBase() : {})
},
createElement: function(nodeName) {
this._nodeName = nodeName;
this.childElements = [];
this._fullSettings = {};
if (this.isVml()) {
var result = createVmlElement('vml:' + nodeName);
return result
}
else
return doc.createElement(nodeName)
},
append: function(element) {
var toElement = element || this.renderer.getRoot();
if (toElement) {
toElement.element.appendChild(this.element);
toElement.childElements.push(this);
if (this.parentElement)
this.parentElement.childElements.splice($.inArray(this, this.parentElement.childElements), 1);
this.parentElement = toElement
}
if (toElement === this.renderer.getRoot() || toElement._isAppended)
this.appendComplete();
return this
},
insertBefore: function(target) {
var parent = target.parentElement;
parent.element.insertBefore(this.element, target.element);
this.parentElement = parent;
parent.childElements.splice($.inArray(target, parent.childElements), 0, this);
parent._isAppended && this.appendComplete();
return this
},
remove: function() {
this.callBase.apply(this, arguments);
if (this.parentElement) {
this.parentElement.childElements.splice($.inArray(this, this.parentElement.childElements), 1);
this.parentElement = null
}
return this
},
detach: function() {
this.callBase.apply(this, arguments);
this._delayAttributes(['opacity']);
this._onDetach();
if (this.parentElement) {
this.parentElement.childElements.splice($.inArray(this, this.parentElement.childElements), 1);
this.parentElement = null
}
return this
},
clear: function() {
this.callBase.apply(this, arguments);
$.each(this.childElements, function(_, element) {
element._delayAttributes(['opacity']);
element._onDetach();
element.parentElement = null
});
this.childElements = [];
return this
},
applyStyle: function(style) {
this.callBase(style);
if (style.opacity)
this.element.style.opacity = style.opacity;
if (style.clip)
try {
this.element.style.clip = style.clip
}
catch(e) {}
},
_fillAttributesFromParentAndCurrentStyle: function(attributes) {
var element = this.element,
parent = this.parentElement,
i,
settingToStyleMap = {strokeWidth: 'stroke-width'},
propertyName,
styleName,
settingsToApply = {};
if (parent)
for (i = 0; i < INHERITABLE_PROPERTIES.length; i++) {
propertyName = INHERITABLE_PROPERTIES[i];
if (!this.settings[propertyName] && parent._fullSettings[propertyName])
settingsToApply[propertyName] = parent._fullSettings[propertyName]
}
if (element.style && element.currentStyle)
for (i = 0; i < INHERITABLE_PROPERTIES.length; i++) {
propertyName = INHERITABLE_PROPERTIES[i];
styleName = settingToStyleMap[propertyName] || propertyName;
if (element.currentStyle[styleName])
settingsToApply[propertyName] = element.currentStyle[styleName]
}
$.extend(this._fullSettings, this.settings, settingsToApply);
if (this.isVml())
$.extend(attributes, this._normalizeSettings(settingsToApply))
},
_applyAttributes: function(params) {
var name,
value;
if (params && params.arcsize !== undefined) {
try {
this.element.setAttribute('arcsize', params.arcsize)
}
catch(e) {}
this.__appliedSettings = {arcsize: params.arcsize};
delete params.arcsize
}
if (params && params['class']) {
this.element.className = params['class'];
delete params['class']
}
if (!this._isAppended)
this._delayedAttributes = params;
else {
params = params || this._delayedAttributes;
if (params) {
this._fillAttributesFromParentAndCurrentStyle(params);
if (this.isVml()) {
for (name in params) {
value = params[name];
if (name === 'opacity' || name === 'fillOpacity' || name === 'strokeOpacity' || name === 'dashstyle' || name === 'joinStyle')
applySubElementAttribute(this, params, name);
else
this.element[name] = value
}
$.each(this.element.children, function(_, e) {
e.style.behavior = 'url(#default#VML)';
e.style.display = 'inline-block';
e.xmlns = "urn:schemas-microsoft-com:vml"
})
}
this.__appliedSettings = this.isVml() ? params : {};
delete this._delayedAttributes
}
}
},
_onDetach: function() {
this._isAppended = false;
$.each(this.childElements, function(_, child) {
child._onDetach()
})
},
appendComplete: function() {
if (this.renderer.isElementAppendedToPage(this)) {
this._isAppended = true;
this._applyAttributes();
$.each(this.childElements, function(_, child) {
child.appendComplete()
});
if (this.parentElement instanceof GroupVmlElement && this.parentElement._clipRect && this.parentElement._clipRect !== this)
if (this.parentElement._clipRect._isAppended)
this.parentElement._clipRect.toForeground();
else
this.parentElement._clipRect.append(this.parentElement)
}
else {
vmlElementsToAppend.push(this);
$(this.element).data('vmlNeedAppendComplete', true);
if (appendTimerID === undefined)
appendTimerID = setTimeout(function() {
appendTimerID = undefined;
var vmlElements = vmlElementsToAppend;
vmlElementsToAppend = [];
$.each(vmlElements, function() {
if ($(this.element).data('vmlNeedAppendComplete') && !this._isAppended)
this.appendComplete()
})
}, 200)
}
},
_delayAttributes: function(attributes) {
var attr,
val,
i,
settings = this.settings || {};
attributes = attributes || [];
this._delayedAttributes = this._delayedAttributes || {};
for (i = 0; i < attributes.length; i++) {
attr = attributes[i];
val = settings[attr];
if (val)
this._delayedAttributes[attr] = val
}
$.each(this.childElements || [], function(_, child) {
child._delayAttributes(attributes)
})
},
_normalizeSettings: function(settings) {
var key,
style = {},
normalized = {},
clipRect,
pos,
prop,
value;
for (key in settings) {
prop = key;
value = settings[prop];
if (prop === 'x' || prop === 'translateX') {
pos = settings.x || 0;
if (settings.translateX)
pos += settings.translateX;
style.left = pos + 'px'
}
else if (prop === 'y' || prop === 'translateY') {
pos = settings.y || 0;
if (settings.translateY)
pos += settings.translateY;
style.top = pos + 'px'
}
else if (prop === 'width')
style.width = value + 'px';
else if (prop === "behavior")
style[prop] = value;
else if (prop === 'height')
style.height = value + 'px';
else if (prop === 'align')
continue;
else if (prop === 'scale')
continue;
else if ($.inArray(prop, CSS_PROPERTIES) != -1)
style[prop] = value !== null ? value : '';
else if (prop === 'font') {
if (!$.isPlainObject(value))
continue;
$.each(value, function(fontSetting) {
var styleName,
firstChar;
switch (fontSetting) {
case'color':
styleName = "fill";
break;
case'opacity':
styleName = "opacity";
break;
case'cursor':
styleName = fontSetting;
break;
default:
firstChar = fontSetting.charAt(0);
styleName = 'font' + fontSetting.replace(firstChar, firstChar.toUpperCase())
}
if (styleName)
style[styleName] = value[fontSetting]
})
}
else if (prop === 'style')
$.extend(true, style, value);
else if (prop === 'rotate')
this['_rotate'] = value;
else if (prop === 'clipId') {
clipRect = this.renderer.getClipRect(value, this);
if (clipRect) {
var width = clipRect.width,
height = clipRect.height,
x = clipRect.x,
y = clipRect.y,
clipWidth = width + x,
clipHeight = height + y,
canvasSize = this.renderer._getSize();
style.width = canvasSize.width;
style.height = canvasSize.height;
style.clip = "rect(" + y + "px, " + clipWidth + "px, " + clipHeight + "px, " + x + "px)"
}
}
else if (prop === 'segments')
continue;
else if (prop === 'fill') {
normalized.filled = value === 'none' ? 'f' : 't';
normalized.fillcolor = value === 'grey' ? '#808080' : value
}
else if (prop === 'opacity')
normalized.opacity = value < 0.002 ? value : value;
else if (prop === 'stroke') {
normalized.stroked = value === 'none' ? 'f' : 't';
normalized.strokecolor = value
}
else if (prop === 'strokeWidth')
normalized.strokeweight = value + 'px';
else if (prop === 'lineJoin')
normalized.joinStyle = value;
else if (prop === 'dashStyle') {
value = (value || "").toLowerCase();
normalized.dashstyle = value
}
else
normalized[prop] = value
}
this['_style'] = style;
return normalized
},
_getBBox: function() {
var width,
height,
rect,
parentRect,
x = 0,
y = 0,
element = this.element,
parent;
try {
rect = getBoundingClientRect(element);
width = rect.right - rect.left;
height = rect.bottom - rect.top;
parent = this.element.parentNode || this.renderer.getRoot().element;
parentRect = parent.getBoundingClientRect();
x = rect.left - parentRect.left;
y = rect.top - parentRect.top;
if (element.tagName.toLowerCase() === 'div') {
x = x - (parseInt(element.style.left, 10) || 0);
y = y - (parseInt(element.style.top, 10) || 0)
}
}
catch(e) {
width = element.offsetWidth || 0;
height = element.offsetHeight || 0
}
return {
x: x,
y: y,
width: width,
height: height,
isEmpty: !x && !y && !width && !height
}
},
getBBox: function() {
return this._getBBox()
},
sharpEdges: function(){}
};
var convertSvgPathCommandToVml = function(command) {
switch (command) {
case'M':
return 'm';
case'L':
return 'l';
case'Z':
return 'x e'
}
return command
};
var BasePathVmlElement = {
defaultSettings: function() {
return $.extend(this.callBase(), {coordsize: '1,1'})
},
getNodeName: function() {
return 'shape'
},
getPathAttributeName: function() {
return 'path'
},
customizeSegments: function(segments) {
var result = segments;
if (segments)
result = $.map(segments, function(s, i) {
var pos,
segmentArray = [],
command = convertSvgPathCommandToVml(s[0]);
segmentArray.push(command);
for (pos = 1; pos < s.length; pos++)
segmentArray.push(Math.floor(s[pos]));
return [segmentArray]
});
return result
}
};
var RootVmlElement = svgRendererInternals.BaseSvgElement.inherit(BaseVmlElement).inherit({
isVml: function() {
return false
},
defaultSettings: function() {
return {
width: 0,
height: 0,
position: 'relative',
display: 'inline-block',
overflow: 'hidden',
stroke: 'none',
strokeWidth: 0,
fill: 'none'
}
},
ctor: function(renderer, params) {
this.callBase(renderer, 'div', params)
}
});
var ImageVmlElement = svgRendererInternals.BaseSvgElement.inherit(svgRendererInternals.RectSvgBaseElement).inherit(BaseVmlElement).inherit({
ctor: function(renderer, params) {
this.callBase(renderer, 'image', params)
},
defaultSettings: function() {
return $.extend(this.callBase(), {
strokeWidth: 0,
fill: 'none',
stroke: 'none'
})
},
adjustSettings: function() {
var defaultSettings = this.defaultSettings();
this.callBase();
if (this.settings.href) {
this.settings.src = this.settings.href;
delete this.settings.href
}
this.settings.fill = defaultSettings.fill;
this.settings.stroke = defaultSettings.stroke;
this.settings.strokeWidth = defaultSettings.strokeWidth
}
});
var RectVmlElement = svgRendererInternals.BaseSvgElement.inherit(svgRendererInternals.RectSvgBaseElement).inherit(BaseVmlElement).inherit({
defaultSettings: function() {
return extendDefaultVmlOptions({
stroked: 'f',
strokeWidth: 0,
rx: 0,
ry: 0
})
},
recreateElement: function(name) {
this._nodeName = name;
var parent = this.$element.parent()[0];
if (parent) {
var $oldElement = this.$element;
this.element = this.createElement(name);
this.$element = $(this.element);
this.$element.insertBefore($oldElement);
$oldElement.remove()
}
else {
this.element = this.createElement(name);
this.$element = $(this.element)
}
this.applySettings()
},
_adjustArcSize: function() {
var settings = this.settings;
var rx = settings.rx || 0,
ry = settings.ry || 0,
width = settings.width,
height = settings.height,
r,
halfsize,
arcsize;
if (settings.rx !== undefined || settings.ry !== undefined) {
r = Math.max(rx, ry);
halfsize = Math.max(width, height) / 2;
arcsize = r / halfsize;
settings.arcsize = arcsize;
if ($.isNumeric(arcsize) && arcsize != 0)
this._nodeName !== 'roundrect' && this.recreateElement('roundrect');
else
this._nodeName === 'roundrect' && this.recreateElement('rect');
delete settings.rx;
delete settings.ry
}
},
_adjustRotation: function() {
var settings = this.settings;
var rotate = this.settings.rotate,
rotateAngle,
radianAngle,
cos,
sin,
rotateX,
rotateY,
marginTop,
marginLeft,
cx,
cy,
rotateObject;
rotateObject = parseRotateParameter(rotate, settings.x, settings.y);
if (rotateObject) {
rotateAngle = rotateObject.angle;
rotateX = rotateObject.x;
rotateY = rotateObject.y;
radianAngle = rotateAngle * Math.PI / 180.0;
cos = Math.cos(radianAngle);
sin = Math.sin(radianAngle);
cx = settings.x + (settings.translateX || 0) + settings.width / 2;
cy = settings.y + (settings.translateY || 0) + settings.height / 2;
marginLeft = (cx - rotateX) * cos - (cy - rotateY) * sin + rotateX - cx;
marginTop = (cx - rotateX) * sin + (cy - rotateY) * cos + rotateY - cy;
this.settings.marginLeft = Math.round(marginLeft) + 'px';
this.settings.marginTop = Math.round(marginTop) + 'px';
this.settings.rotation = rotateAngle
}
},
adjustSettings: function() {
this.callBase();
this._adjustArcSize();
this._adjustRotation()
},
ctor: function(renderer, params) {
this.callBase(renderer, 'rect', params)
}
});
var PathVmlElement = svgRendererInternals.PathSvgElement.inherit(BaseVmlElement).inherit(BasePathVmlElement).inherit({prepareSegments: function(settings) {
var that = this,
rotate = settings.rotate,
rotateAngle,
rotateX,
rotateY,
oldSegments,
radianAngle,
cos,
sin,
x,
y,
rotatedX,
rotatedY,
rotateObject;
this.callBase(settings);
oldSegments = that.segments;
rotateObject = parseRotateParameter(rotate, settings.x, settings.y);
if (rotateObject) {
rotateAngle = rotateObject.angle;
rotateX = rotateObject.x;
rotateY = rotateObject.y;
if (that.segments) {
radianAngle = rotateAngle * Math.PI / 180.0;
cos = Math.cos(radianAngle);
sin = Math.sin(radianAngle);
that.segments = $.map(that.segments, function(s, i) {
if (s.length === 3) {
x = s[1],
y = s[2];
rotatedX = (x - rotateX) * cos - (y - rotateY) * sin + rotateX;
rotatedY = (x - rotateX) * sin + (y - rotateY) * cos + rotateY;
return [[s[0], Math.floor(rotatedX), Math.floor(rotatedY)]]
}
else
return [s]
});
that.combinePathParams(settings);
that.segments = oldSegments
}
}
}});
var SimplePathVmlElement = svgRendererInternals.BaseSvgElement.inherit(BaseVmlElement).inherit({
ctor: function(renderer, options) {
this.callBase(renderer, 'shape', options)
},
defaultSettings: function() {
return extendDefaultVmlOptions({coordsize: '1,1'})
},
adjustSettings: function() {
var settings = this.settings;
if (settings.d !== undefined) {
settings.path = settings.d;
delete settings.d
}
}
});
var AreaVmlElement = PathVmlElement.inherit({
defaultSettings: function() {
var baseOptions = this.callBase();
return extendDefaultVmlOptions({points: {
x: 0,
y: 0
}}, baseOptions)
},
ctor: function(renderer, params) {
this.closePath = true;
this.callBase(renderer, params)
}
});
var SegmentRectVmlElement = svgRendererInternals.SegmentRectSvgElement.inherit(BaseVmlElement).inherit(BasePathVmlElement).inherit({
defaultSettings: function() {
var settings = this.callBase();
settings.lineJoin = 'miter';
delete settings.fill;
delete settings.stroke;
delete settings.strokecolor;
delete settings.stroked;
return settings
},
prepareSegments: function() {
this.callBase();
this.segments = this.customizeSegments(this.segments);
this.settings.x = 0;
this.settings.y = 0;
this.settings.width = 1;
this.settings.height = 1
},
applySettings: function(settings) {
var x = settings.x,
y = settings.y,
w = settings.width,
h = settings.height;
this.callBase(settings);
this.settings.x = x;
this.settings.y = y;
this.settings.width = w;
this.settings.height = h;
return this
}
});
var BezierVmlElement = svgRendererInternals.BezierSvgElement.inherit(BaseVmlElement).inherit(BasePathVmlElement);
var BezierAreaVmlElement = BezierVmlElement.inherit({
defaultSettings: function() {
var baseOptions = this.callBase();
return extendDefaultVmlOptions({points: {
x: 0,
y: 0
}}, baseOptions)
},
ctor: function(renderer, params) {
this.closePath = true;
this.callBase(renderer, params)
}
});
var ArcVmlElement = svgRendererInternals.ArcSvgElement.inherit(BaseVmlElement).inherit(BasePathVmlElement).inherit({createArcSegments: function(x, y, innerR, outerR, startAngle, endAngle, isCircle) {
var xOuterStart = x + outerR * Math.cos(startAngle),
yOuterStart = y - outerR * Math.sin(startAngle),
xOuterEnd = x + outerR * Math.cos(endAngle),
yOuterEnd = y - outerR * Math.sin(endAngle),
xInnerStart = x + innerR * Math.cos(endAngle),
yInnerStart = y - innerR * Math.sin(endAngle),
xInnerEnd = x + innerR * Math.cos(startAngle),
yInnerEnd = y - innerR * Math.sin(startAngle);
return [['wr', x - innerR, y - innerR, x + innerR, y + innerR, xInnerStart, yInnerStart, xInnerEnd, yInnerEnd], [isCircle ? 'wr' : 'at', x - outerR, y - outerR, x + outerR, y + outerR, xOuterStart, yOuterStart, xOuterEnd, yOuterEnd], ['x e']]
}});
var CircleVmlElement = svgRendererInternals.BaseSvgElement.inherit(BaseVmlElement).inherit({
defaultSettings: function() {
return extendDefaultVmlOptions({
cx: 0,
cy: 0,
r: 0
})
},
applySettings: function(settings) {
settings.cx = settings.cx || settings.x;
settings.cy = settings.cy || settings.y;
return this.callBase(settings)
},
adjustSettings: function() {
var r,
cx,
cy;
if (this.settings.cx !== undefined || this.settings.cy !== undefined || this.settings.r !== undefined) {
r = 'r' in this.settings ? this.settings.r : this.settings.width / 2;
cx = 'cx' in this.settings ? this.settings.cx : this.settings.x + this.settings.width / 2;
cy = 'cy' in this.settings ? this.settings.cy : this.settings.y + this.settings.width / 2;
this.settings.x = cx - r;
this.settings.y = cy - r;
this.settings.width = this.settings.height = r * 2;
delete this.settings.cx;
delete this.settings.cy;
delete this.settings.r
}
},
ctor: function(renderer, params) {
this.callBase(renderer, 'oval', params)
}
});
var TextVmlElement = svgRendererInternals.BaseSvgElement.inherit(BaseVmlElement).inherit({
isVml: function() {
return false
},
defaultSettings: function() {
return {
x: 0,
y: 0,
position: 'absolute',
whiteSpace: 'nowrap'
}
},
ctor: function(renderer, params) {
this.callBase(renderer, 'span', params)
},
adjustSettings: function() {
var text,
settings = this.settings;
if (settings.font) {
settings.fill = settings.fill || settings.font.color;
settings.opacity = settings.opacity || settings.font.opacity
}
if ('text' in settings) {
text = utils.isDefined(settings.text) ? settings.text : '';
text = text.toString().replace(/\r/g, "");
text = text.replace(/\n/g, "
");
$(this.element).html(text);
delete settings.text
}
if (this.renderer.rtl)
$(this.element).css('direction', 'rtl')
},
updateText: function(text) {
this.applySettings({text: utils.isDefined(text) ? text : ''})
},
_applyAttributes: function(settings) {
this.callBase(settings);
settings = this._fullSettings;
var rotate = settings.rotate,
rotateAngle = 0,
rotateX,
rotateY,
cos = 1,
sin = 0,
osin = 0,
ocos = 1,
angle,
otg,
rad,
y = settings.y + (settings.translateY || 0),
x = settings.x + (settings.translateX || 0),
align = settings.align,
bBox = this.getBBox(),
style = this._style || {},
marginLeft = 0,
marginTop = 0,
fontHeightOffset,
alignMultiplier,
rotateObject,
textWidth,
textHeight;
if (this._oldRotate && !bBox.isEmpty) {
rad = this._oldRotate.angle * Math.PI / 180.0;
osin = Math.sin(rad);
ocos = Math.cos(rad);
if ((this._oldRotate.angle | 0) % 90 !== 0)
if ((this._oldRotate.angle | 0) % 45 === 0)
textWidth = bBox.width,
textHeight = bBox.height;
else {
otg = Math.abs(Math.tan(rad));
var b = (bBox.width - bBox.height * otg) / (1 - otg * otg);
var a = bBox.width - b;
textHeight = Math.abs(a / osin);
textWidth = Math.abs(b / ocos)
}
else {
textHeight = Math.abs(bBox.height * ocos - bBox.width * osin);
textWidth = Math.abs(bBox.width * ocos - bBox.height * osin)
}
}
else
textWidth = bBox.width,
textHeight = bBox.height;
this.__textWidth = textWidth;
this.__textHeight = textHeight;
if (textHeight || textWidth) {
rotateObject = parseRotateParameter(rotate, x, y);
this._oldRotate = rotateObject;
if (rotateObject) {
rotateAngle = rotateObject.angle;
rotateX = rotateObject.x;
rotateY = rotateObject.y;
if (Math.abs(rotateAngle) > 360)
rotateAngle = rotateAngle % 360;
if (rotateAngle < 0)
rotateAngle = rotateAngle + 360;
if (rotateAngle) {
rad = rotateAngle * Math.PI / 180.0;
cos = Math.cos(rad);
sin = Math.sin(rad);
style.filter = 'progid:DXImageTransform.Microsoft.Matrix(sizingMethod="auto expand", M11 = ' + cos.toFixed(5) + ', M12 = ' + (-sin).toFixed(5) + ', M21 = ' + sin.toFixed(5) + ', M22 = ' + cos.toFixed(5) + ')'
}
else {
style.filter = '';
this._oldRotate = null
}
marginLeft = (x - rotateX) * (cos - 1) - (y - rotateY) * sin;
marginTop = (x - rotateX) * sin + (y - rotateY) * (cos - 1)
}
fontHeightOffset = textHeight * (0.55 + 0.45 / 2);
if (rotateAngle < 90) {
marginTop -= fontHeightOffset * cos;
marginLeft -= (textHeight - fontHeightOffset) * sin
}
else if (rotateAngle < 180) {
marginTop += (textHeight - fontHeightOffset) * cos;
marginLeft += textWidth * cos - (textHeight - fontHeightOffset) * sin
}
else if (rotateAngle < 270) {
marginTop += (textHeight - fontHeightOffset) * cos + textWidth * sin;
marginLeft += textWidth * cos + fontHeightOffset * sin
}
else {
marginTop += textWidth * sin - fontHeightOffset * cos;
marginLeft += fontHeightOffset * sin
}
if (rotateAngle && this.renderer.rtl)
marginLeft -= textWidth - (textHeight * Math.abs(sin) + textWidth * Math.abs(cos));
alignMultiplier = {
center: 0.5,
right: 1
}[align];
if (alignMultiplier) {
marginLeft -= textWidth * alignMultiplier * cos;
marginTop -= textWidth * alignMultiplier * sin
}
style.marginLeft = Math.round(marginLeft) + 'px';
style.marginTop = Math.round(marginTop) + 'px'
}
if (settings.fill && settings.fill !== 'none')
style.color = settings.fill;
if (settings.opacity)
this.element.style.filter = 'alpha(opacity=' + settings.opacity * 100 + ')';
this.applyStyle(style)
}
});
var GroupVmlElement = svgRendererInternals.BaseSvgElement.inherit(BaseVmlElement).inherit({
isVml: function() {
return false
},
defaultSettings: function() {
return {
x: 0,
y: 0,
position: 'absolute'
}
},
ctor: function(renderer, params) {
this.callBase(renderer, 'div', params)
},
adjustSettings: function() {
if (this.settings.clipId || this._clipRect) {
var rect = this.renderer.getClipRect(this.settings.clipId, this);
if (this._clipRect)
if (rect)
this._clipRect.applySettings({
x: rect.x,
y: rect.y,
width: rect.width,
height: rect.height
});
else {
this._clipRect.remove();
this._clipRect = null
}
else
this._clipRect = this.renderer.createRect(rect.x, rect.y, rect.width, rect.height, 0, {
fill: "none",
opacity: 0.002,
"class": CLIP_RECT_CLASS
});
if (this._clipRect)
this.childElements.length && this._clipRect.append(this)
}
},
applySettings: function(settings) {
var rotate;
settings = settings || {};
rotate = settings.rotate;
if (rotate) {
if (utils.isNumber(rotate))
rotate = [rotate, settings.x || 0, settings.y || 0];
$.each(this.childElements, function(_, child) {
child.applySettings({rotate: rotate})
})
}
delete settings.rotate;
delete settings.x;
delete settings.y;
this.callBase(settings);
$.each(this.childElements || [], function(_, c) {
c.applySettings({})
});
return this
},
getBBox: function() {
return this._getBBox()
},
update: function() {
if (this.settings.clipId) {
var bbox = this.getBBox();
this.applyStyle({
left: bbox.x + (this.settings.translateX || 0),
right: bbox.y + (this.settings.translateY || 0),
width: bbox.width,
height: bbox.height
})
}
}
});
renderers.VmlRenderer = renderers.SvgRenderer.inherit({
ctor: function(options) {
options = options || {};
options.animation = {enabled: false};
if (doc.namespaces && !doc.namespaces.vml) {
doc.namespaces.add('vml', 'urn:schemas-microsoft-com:vml');
var cssText = 'vml\\:fill, vml\\:path, vml\\:shape, vml\\:stroke, vml\\:rect, vml\\:oval' + '{ behavior:url(#default#VML); display: inline-block; };';
try {
doc.createStyleSheet().cssText = cssText
}
catch(e) {
doc.styleSheets[0].cssText += cssText
}
}
this._clipRects = {};
this.cssClass = options.cssClass || '';
this.callBase(options)
},
dispose: function() {
this.callBase();
this._clipRects = null;
this._size = null
},
updateAnimationOptions: $.noop,
draw: function(container) {
var root = this.getRoot();
this.callBase(container);
if (root)
root.appendComplete()
},
recreateCanvas: function(width, height, cssClass) {
if (width >= 0 && height >= 0) {
this._size = {
width: width,
height: height
};
if (!this.svgRoot) {
this.cssClass = cssClass || this.cssClass;
this.svgRoot = new RootVmlElement(this, {
width: width,
height: height,
'class': this.cssClass
})
}
else
this.svgRoot.applySettings({
width: width,
height: height
});
this.defsSvg && this.defsSvg.clear()
}
},
_getSize: function() {
return this._size || {}
},
isElementAppendedToPage: function(element) {
return $(element.element).closest(doc.documentElement).length
},
createRect: function(x, y, w, h, r, options) {
var params = $.extend(true, {}, options || {}, {
x: x,
y: y,
width: w,
height: h,
rx: r,
ry: r
});
return new RectVmlElement(this, params)
},
createSegmentRect: function(x, y, w, h, r, segments, options) {
var params = $.extend({}, options || {}, {
x: x,
y: y,
width: w,
height: h,
rx: r,
ry: r,
segments: segments
});
return new SegmentRectVmlElement(this, params)
},
createClipRect: function(x, y, width, height) {
var clipId = utils.getNextDefsSvgId(),
elements = [],
clipRect = {
id: clipId,
x: x,
y: y,
width: width,
height: height,
addElement: function(element) {
var hasElement = false;
$.each(elements, function() {
if (this === element) {
hasElement = true;
return false
}
});
if (!hasElement)
elements.push(element)
},
append: function() {
return this
},
remove: function(){},
dispose: function(){},
updateRectangle: function(settings) {
if ('x' in settings)
this.x = settings.x;
if ('translateX' in settings)
this.x += settings.translateX;
if ('y' in settings)
this.y = settings.y;
if ('translateY' in settings)
this.y += settings.translateY;
if ('width' in settings)
this.width = settings.width;
if ('height' in settings)
this.height = settings.height;
$.each(elements, function() {
this.applySettings({clipId: clipId})
});
return this
}
};
this._clipRects[clipId] = clipRect;
return clipRect
},
getClipRect: function(clipId, element) {
var clipRect = this._clipRects[clipId];
if (clipRect && element)
clipRect.addElement(element);
return this._clipRects[clipId]
},
createImage: function(x, y, w, h, href, options) {
var params = $.extend(true, {}, options && !options.inh ? options : {}, {
x: x,
y: y,
width: w,
height: h,
href: href
});
return new ImageVmlElement(this, params)
},
createLine: function(x1, y1, x2, y2, options) {
var params = $.extend(true, {}, options && !options.inh ? options : {}, {points: [x1, y1, x2, y2]});
return new PathVmlElement(this, params)
},
createPath: function(points, options) {
var params = $.extend(true, {}, options && !options.inh ? options : {}, {points: points});
return new PathVmlElement(this, params)
},
createSimplePath: function(options) {
return new SimplePathVmlElement(this, options)
},
createBezierPath: function(points, options) {
var params = $.extend(true, {}, options && !options.inh ? options : {}, {points: points});
return new BezierVmlElement(this, params)
},
createArea: function(points, options) {
var params = $.extend(true, {}, options && !options.inh ? options : {}, {points: points});
return new AreaVmlElement(this, params)
},
createBezierArea: function(points, options) {
var params = $.extend(true, {}, options && !options.inh ? options : {}, {points: points});
return new BezierAreaVmlElement(this, params)
},
createCircle: function(x, y, r, options) {
var params = $.extend(true, {}, options && !options.inh ? options : {}, {
cx: x,
cy: y,
r: r
});
return new CircleVmlElement(this, params)
},
createArc: function(x, y, outerRadius, innerRadius, startAngle, endAngle, options) {
var params = $.extend(true, {}, options && !options.inh ? options : {}, {
x: x,
y: y,
outerRadius: outerRadius,
innerRadius: innerRadius,
startAngle: startAngle,
endAngle: endAngle
});
return new ArcVmlElement(this, params)
},
createText: function(text, x, y, options) {
var params = $.extend(true, {}, options && !options.inh ? options : {}, {
x: x,
y: y,
text: text
});
return new TextVmlElement(this, params)
},
createGroup: function(options) {
return new GroupVmlElement(this, options)
},
createPattern: function(color, hatching) {
return {
id: color,
append: function() {
return this
},
clear: function(){},
dispose: function(){}
}
},
createFilter: function(type) {
if (type === 'shadow')
return {
ref: null,
append: function() {
return this
},
dispose: function() {
return this
},
applySettings: function() {
return this
}
};
return null
},
svg: function() {
return ''
}
});
function buildPath(points) {
var i = 0,
ii = points.length,
list = [];
for (; i < ii; )
list.push('l', points[i++].toFixed(0), points[i++].toFixed(0));
if (ii) {
list[0] = 'm';
list.push('x e');
list = list.join(' ')
}
else
list = '';
return list
}
function processCircleSettings(x, y, size) {
return {
cx: x,
cy: y,
r: size / 2
}
}
renderers._vmlBuildPath = buildPath;
renderers._vmlProcessCircleSettings = processCircleSettings;
renderers.__vmlRendererInternals = {
RootVmlElement: RootVmlElement,
RectVmlElement: RectVmlElement,
ImageVmlElement: ImageVmlElement,
PathVmlElement: PathVmlElement,
AreaVmlElement: AreaVmlElement,
BezierVmlElement: BezierVmlElement,
BezierAreaVmlElement: BezierAreaVmlElement,
SimplePathVmlElement: SimplePathVmlElement,
CircleVmlElement: CircleVmlElement,
TextVmlElement: TextVmlElement,
GroupVmlElement: GroupVmlElement,
ArcVmlElement: ArcVmlElement,
SegmentRectVmlElement: SegmentRectVmlElement
}
})(jQuery, DevExpress);
/*! Module viz-core, file renderer.js */
(function($, DX) {
var renderers = DX.viz.renderers,
browser = DX.browser;
function isSvg() {
return !(browser.msie && browser.version < 9) || !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', "svg").createSVGRect
}
if (!isSvg()) {
renderers.Renderer = renderers.VmlRenderer;
renderers.buildPath = renderers._vmlBuildPath;
renderers.processCircleSettings = renderers._vmlProcessCircleSettings
}
else {
renderers.Renderer = renderers.SvgRenderer;
renderers.buildPath = renderers._svgBuildPath;
renderers.processCircleSettings = renderers._svgProcessCircleSettings
}
renderers.isSvg = isSvg
})(jQuery, DevExpress);
/*! Module viz-core, file animation.js */
(function(DX) {
var renderers = DX.viz.renderers,
Class = DX.Class,
noop = function(){},
easingFunctions = {
easeOutCubic: function(pos, start, end) {
return pos === 1 ? end : (1 - Math.pow(1 - pos, 3)) * (end - start) + +start
},
linear: function(pos, start, end) {
return pos === 1 ? end : pos * (end - start) + +start
}
};
renderers.easingFunctions = easingFunctions;
renderers.animationSvgStep = {
points: function(elem, params, progress, easing, currentParams) {
var from = params.from,
to = params.to,
path = [],
i,
j,
seg,
d;
for (i = 0; i < from.length; i++) {
seg = [from[i][0]];
if (from[i].length > 1)
for (j = 1; j < from[i].length; j++)
seg.push(easing(progress, from[i][j], to[i][j]));
path[i] = seg.join(' ')
}
d = path.join(' ');
currentParams.d = params.end && progress === 1 ? params.end : d;
elem.element.setAttribute('d', d)
},
arc: function(elem, params, progress, easing) {
var from = params.from,
to = params.to,
current = {};
for (var i in from)
current[i] = easing(progress, from[i], to[i]);
elem.applySettings(current)
},
transform: function(elem, params, progress, easing, currentParams) {
var translate = params.translate,
rotate = params.rotate,
scale = params.scale,
transformations = [],
elemSettings = elem.settings;
if (translate) {
currentParams.translateX = easing(progress, translate.x.from, translate.x.to);
currentParams.translateY = easing(progress, translate.y.from, translate.y.to);
transformations.push('translate(' + currentParams.translateX + ',' + currentParams.translateY + ')')
}
else if (elemSettings.translateX || elemSettings.translateY)
transformations.push('translate(' + (elemSettings.translateX || 0) + ',' + (elemSettings.translateY || 0) + ')');
if (rotate) {
currentParams.rotate = {
angle: easing(progress, rotate.angle.from, rotate.angle.to),
x: rotate.x,
y: rotate.y
};
transformations.push('rotate(' + currentParams.rotate.angle + ',' + rotate.x + ',' + rotate.y + ')')
}
else if (elemSettings.rotate)
transformations.push('rotate(' + elemSettings.rotate.angle + ',' + (elemSettings.rotate.x || 0) + ',' + (elemSettings.rotate.y || 0) + ')');
if (scale) {
currentParams.scale = {
x: easing(progress, scale.x.from, scale.x.to),
y: easing(progress, scale.y.from, scale.y.to)
};
transformations.push('scale(' + currentParams.scale.x + ',' + currentParams.scale.y + ')')
}
else if (elemSettings.scale)
transformations.push('scale(' + elemSettings.scale.x + ',' + elemSettings.scale.y + ')');
elem.element.setAttribute('transform', transformations.join())
},
base: function(elem, params, progress, easing, currentParams, attributeName) {
currentParams[attributeName] = easing(progress, params.from, params.to);
elem.element.setAttribute(attributeName, currentParams[attributeName])
},
_: noop,
complete: function(element, currentSettings) {
element.applySettings(currentSettings)
}
};
var Animation = Class.inherit({
ctor: function(element, params, options) {
var that = this;
that._progress = 0;
that.element = element;
that.params = params;
that.options = options;
that.duration = options.partitionDuration ? options.duration * options.partitionDuration : options.duration;
that._animateStep = options.animateStep || renderers.animationSvgStep;
that._easing = easingFunctions[options.easing] || easingFunctions['easeOutCubic'];
that._currentParams = {};
that.tick = that._start
},
_calcProgress: function(now) {
return Math.min(1, (now - this._startTime) / this.duration)
},
_step: function(now) {
var that = this,
animateStep = that._animateStep,
attrName;
that._progress = that._calcProgress(now);
for (attrName in that.params) {
if (!that.params.hasOwnProperty(attrName))
continue;
var anim = animateStep[attrName] || animateStep.base;
anim(that.element, that.params[attrName], that._progress, that._easing, that._currentParams, attrName)
}
that.options.step && that.options.step(that._easing(that._progress, 0, 1), that._progress);
if (that._progress === 1)
return that.stop();
return true
},
_start: function(now) {
this._startTime = now;
this.tick = this._step;
return true
},
_end: function(disableComplete) {
var that = this;
that.stop = noop;
that.tick = noop;
that._animateStep.complete && that._animateStep.complete(that.element, that._currentParams);
that.options.complete && !disableComplete && that.options.complete()
},
tick: function(now) {
return true
},
stop: function(breakAnimation, disableComplete) {
var options = this.options;
if (!breakAnimation && options.repeatCount && --options.repeatCount > 0) {
this.tick = this._start;
return true
}
else
this._end(disableComplete)
}
});
renderers.AnimationController = Class.inherit(function() {
var FPS = 1000 / 60,
requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
setTimeout(callback, FPS)
};
return {
ctor: function() {
var that = this;
that.requestAnimationFrame = requestAnimationFrame;
that._animationCount = 0;
that._timerId = null;
that._animations = {}
},
_loop: function() {
var that = this,
animations = that._animations,
activeAnimation = 0,
now = (new Date).getTime(),
an;
for (an in animations) {
if (!animations.hasOwnProperty(an))
continue;
if (!animations[an].tick(now))
delete animations[an];
activeAnimation++
}
if (activeAnimation === 0) {
that.stop();
return
}
that._timerId = that.requestAnimationFrame.call(null, function() {
that._loop()
}, that.element)
},
addAnimation: function(animation) {
var that = this;
that._animations[that._animationCount++] = animation;
if (!that._timerId) {
clearTimeout(that._startDelay);
that._startDelay = setTimeout(function() {
that._timerId = 1;
that._loop()
}, 0)
}
},
animateElement: function(elem, params, options) {
if (elem && params && options) {
elem.animation && elem.animation.stop(true);
this.addAnimation(elem.animation = new Animation(elem, params, options))
}
},
dispose: function() {
this.stop();
this.element = null
},
stop: function() {
this._animations = {};
this._animationCount = 0;
clearTimeout(this._startDelay);
this._timerId = null
},
lock: function() {
var animations = this._animations;
for (var an in animations)
animations.hasOwnProperty(an) && animations[an].stop(true, true);
this.stop()
}
}
}());
renderers.Animation = Animation;
renderers.noop = noop
})(DevExpress);
/*! Module viz-core, file namespaces.js */
(function(DevExpress) {
DevExpress.viz.charts = {series: {}}
})(DevExpress);
/*! Module viz-core, file chartsConsts.js */
(function(DX) {
DX.viz.charts.consts = {
dataTypes: {
STRING: 'string',
NUMERIC: 'numeric',
DATETIME: 'datetime'
},
axisTypes: {
DISCRETE: 'discrete',
CONTINUOUS: 'continuous',
LOGARITHMIC: 'logarithmic'
}
}
})(DevExpress);
/*! Module viz-core, file dataValidator.js */
(function($, DX) {
var viz = DX.viz,
parseUtils = new viz.core.ParseUtils,
chartConst = viz.charts.consts,
dataTypes = chartConst.dataTypes,
axisTypes = chartConst.axisTypes,
utils = DX.utils,
_each = $.each,
_isDefined = utils.isDefined;
var mergeSort = function(data, field) {
function merge_sort(array, low, high, field) {
if (low < high) {
var mid = Math.floor((low + high) / 2);
merge_sort(array, low, mid, field);
merge_sort(array, mid + 1, high, field);
merge(array, low, mid, high, field)
}
}
var n = data.length;
merge_sort(data, 0, n - 1, field);
return data
};
var merge = function(array, low, mid, high, field) {
var newArray = new Array(high - low + 1),
countL = low,
countR = mid + 1,
k,
i = 0;
while (countL <= mid && countR <= high) {
if (array[countL][field] <= array[countR][field] || !_isDefined(array[countR][field])) {
newArray[i] = array[countL];
countL++
}
else {
newArray[i] = array[countR];
countR++
}
i++
}
if (countL > mid)
for (k = countR; k <= high; k++, i++)
newArray[i] = array[k];
else
for (k = countL; k <= mid; k++, i++)
newArray[i] = array[k];
for (k = 0; k <= high - low; k++)
array[k + low] = newArray[k];
return array
};
viz.charts.DataValidator = DX.Class.inherit({
ctor: function(data, groups, incidentOccured, dataPrepareOptions) {
var that = this;
groups = groups || [[]];
if (!data)
that._nullData = true;
that.groups = groups;
that.data = data || [];
that._parsers = {};
that._errorShowList = {};
that._skipFields = {};
that.options = dataPrepareOptions || {};
that.incidentOccured = incidentOccured;
that.userArgumentCategories = that.groups.length && that.groups[0].length && that.groups[0][0].getArgumentCategories();
if (!incidentOccured)
that.incidentOccured = $.noop
},
validate: function validate() {
var that = this;
that._data = that.data;
if (!utils.isArray(that.data) || that._nullData)
that._incorrectDataMessage();
that.groups.argumentType = null;
that.groups.argumentAxisType = null;
$.each(that.groups, function(_, group) {
group.valueType = null;
group.valueAxisType = null;
$.each(group, function(_, series) {
series.updateDataType({})
})
});
that._checkType();
that._checkAxisType();
if (that.options.convertToAxisDataType) {
that._createParser();
that._parse()
}
that._groupData();
that._sort();
$.each(that._skipFields, function(field, fieldValue) {
if (fieldValue === that._data.length)
that.incidentOccured("W2002", [field])
});
return that._data
},
_checkType: function _checkType() {
var that = this,
groupsWithUndefinedValueType = [],
groupsWithUndefinedArgumentType = [],
checkValueTypeOfGroup = function checkValueTypeOfGroup(group, cell) {
$.each(group, function(_, series) {
$.each(series.getValueFields(), function(_, field) {
group.valueType = that._getType(cell[field], group.valueType)
})
});
if (group.valueType)
return true
},
checkArgumentTypeOfGroup = function checkArgumentTypeOfGroup(group, cell) {
$.each(group, function(_, series) {
that.groups.argumentType = that._getType(cell[series.getArgumentField()], that.groups.argumentType)
});
if (that.groups.argumentType)
return true
};
$.each(that.groups, function(_, group) {
if (!group.length)
return null;
var options = group[0].getOptions(),
valueTypeGroup = options.valueType,
argumentTypeGroup = options.argumentType;
group.valueType = valueTypeGroup;
that.groups.argumentType = argumentTypeGroup;
valueTypeGroup ? null : groupsWithUndefinedValueType.push(group);
argumentTypeGroup ? null : groupsWithUndefinedArgumentType.push(group)
});
if (groupsWithUndefinedValueType.length || groupsWithUndefinedArgumentType.length)
$.each(that.data, function(_, cell) {
var define = true;
if (!utils.isObject(cell))
return;
$.each(groupsWithUndefinedValueType, function(index, group) {
define = define && checkValueTypeOfGroup(group, cell)
});
$.each(groupsWithUndefinedArgumentType, function(index, group) {
define = define && checkArgumentTypeOfGroup(group, cell)
});
if (!that.options.checkTypeForAllData && define)
return false
})
},
_checkAxisType: function _checkAxisType() {
var that = this;
$.each(that.groups, function(_, group) {
$.each(group, function(_, series) {
var optionsSeries = {},
existingSeriesOptions = series.getOptions();
optionsSeries.argumentAxisType = that._correctAxisType(that.groups.argumentType, existingSeriesOptions.argumentAxisType, !!that.userArgumentCategories.length);
optionsSeries.valueAxisType = that._correctAxisType(group.valueType, existingSeriesOptions.valueAxisType, !!series.getValueCategories().length);
that.groups.argumentAxisType = that.groups.argumentAxisType || optionsSeries.argumentAxisType;
group.valueAxisType = group.valueAxisType || optionsSeries.valueAxisType;
optionsSeries.argumentType = that.groups.argumentType;
optionsSeries.valueType = group.valueType;
series.updateDataType(optionsSeries)
})
})
},
_createParser: function _createParser() {
var that = this;
$.each(that.groups, function(index, group) {
$.each(group, function(_, series) {
that._parsers[series.getArgumentField()] = that._createParserUnit(that.groups.argumentType, that.groups.argumentAxisType === axisTypes.LOGARITHMIC ? that._filterForLogAxis : null);
$.each(series.getValueFields(), function(_, field) {
that._parsers[field] = that._createParserUnit(group.valueType, group.valueAxisType === axisTypes.LOGARITHMIC ? that._filterForLogAxis : null, series.getOptions().ignoreEmptyPoints)
});
if (series.getTagField())
that._parsers[series.getTagField()] = null
})
})
},
_parse: function _parse() {
var that = this,
parsedData = [];
$.each(that.data, function(_, cell) {
var parserObject = {};
if (!utils.isObject(cell)) {
cell && that._incorrectDataMessage();
return
}
$.each(that._parsers, function(field, parser) {
parserObject[field] = parser ? parser(cell[field], field) : cell[field];
parserObject['original' + field] = cell[field]
});
parsedData.push(parserObject)
});
this._data = parsedData
},
_groupMinSlices: function(argumentField, valueField, smallValuesGrouping) {
var that = this,
smallValuesGrouping = smallValuesGrouping || {},
mode = smallValuesGrouping.mode,
count = smallValuesGrouping.topCount,
threshold = smallValuesGrouping.threshold,
name = smallValuesGrouping.groupName || 'others',
others = {},
data = that._data.slice(),
index;
var groupingValues = function(index) {
if (!_isDefined(index) || index < 0)
return;
_each(data.slice(index), function(_, cell) {
if (!_isDefined(cell[valueField]))
return;
others[valueField] += cell[valueField];
cell[valueField] = undefined;
cell['original' + valueField] = undefined
})
};
if (!mode || mode === 'none')
return;
others[argumentField] = name + '';
others[valueField] = 0;
data.sort(function(a, b) {
if (_isDefined(b[valueField]) && _isDefined(a[valueField]))
return b[valueField] - a[valueField];
else if (!_isDefined(b[valueField]) && a[valueField])
return -1;
else if (!_isDefined(a[valueField]) && b[valueField])
return 1
});
if (mode === 'smallValueThreshold') {
_each(data, function(i, cell) {
if (_isDefined(index) || !_isDefined(cell[valueField]))
return;
if (threshold > cell[valueField])
index = i
});
groupingValues(index)
}
else if (mode === 'topN')
groupingValues(count);
others[valueField] && that._data.push(others)
},
_groupData: function() {
var that = this,
groups = that.groups,
isPie = groups.length && groups[0].length && (groups[0][0].type === 'pie' || groups[0][0].type === 'doughnut' || groups[0][0].type === 'donut'),
argumentField,
valueFields;
if (!isPie)
return;
_each(groups, function(_, group) {
_each(group, function(_, series) {
argumentField = series.getArgumentField();
valueFields = series.getValueFields();
if (groups.argumentAxisType === axisTypes.DISCRETE)
that._groupSameArguments(argumentField, valueFields);
that._groupMinSlices(argumentField, valueFields[0], series.getOptions().smallValuesGrouping)
})
})
},
_groupSameArguments: function(argumentField, valueFields) {
var that = this,
argument,
dataOfArguments = {},
parsedData = that._data;
_each(parsedData, function(i, cell) {
if (!_isDefined(cell[argumentField]) || !_isDefined(cell[valueFields[0]]))
return;
argument = cell[argumentField];
if (_isDefined(dataOfArguments[argument])) {
var data = parsedData[dataOfArguments[argument]];
_each(valueFields, function(_, field) {
data[field] += cell[field];
cell[field] = undefined;
cell['original' + field] = undefined
})
}
else
dataOfArguments[argument] = i
})
},
_getType: function _getType(unit, type) {
if (type === dataTypes.STRING || utils.isString(unit))
return dataTypes.STRING;
if (type === dataTypes.DATETIME || utils.isDate(unit))
return dataTypes.DATETIME;
if (utils.isNumber(unit))
return dataTypes.NUMERIC;
return type
},
_correctAxisType: function _correctAxisType(type, axisType, hasCategories) {
if (type === dataTypes.STRING && (axisType === axisTypes.CONTINUOUS || axisType === axisTypes.LOGARITHMIC))
this.incidentOccured("E2002");
if (axisType === axisTypes.LOGARITHMIC)
return axisTypes.LOGARITHMIC;
axisType = (hasCategories || axisType === axisTypes.DISCRETE || type === dataTypes.STRING) && axisTypes.DISCRETE;
return axisType || axisTypes.CONTINUOUS
},
_filterForLogAxis: function(val, field) {
if (val <= 0) {
this.incidentOccured("E2004", [field]);
return null
}
return val
},
_createParserUnit: function _createParserUnit(type, filter, ignoreEmptyPoints) {
var that = this,
parser = type ? parseUtils.getParser(type, undefined, true) : function(unit) {
return unit
};
return function(unit, field) {
var parseUnit = parser(unit);
if (filter)
parseUnit = filter.call(that, parseUnit, field);
parseUnit === null && ignoreEmptyPoints && (parseUnit = undefined);
if (parseUnit === undefined) {
that._addSkipFields(field);
that._validUnit(unit, field, type)
}
return parseUnit
}
},
_validUnit: function _validUnit(unit, field, type) {
if (!unit)
return;
if (!utils.isNumber(unit) && !utils.isDate(unit) && !utils.isString(unit)) {
this.incidentOccured("E2003", [field]);
return
}
this.incidentOccured("E2004", [field])
},
_sort: function _sort() {
var that = this,
groups = that.groups,
hash = {},
argumentField = groups.length && groups[0].length && groups[0][0].getArgumentField();
if (utils.isFunction(that.options.sortingMethod))
that._data.sort(that.options.sortingMethod);
else if (that.userArgumentCategories.length) {
$.each(that.userArgumentCategories, function(index, value) {
hash[value] = index
});
that._data.sort(function sortCat(a, b) {
a = a[argumentField];
b = b[argumentField];
return hash[a] - hash[b]
})
}
else if (that.options.sortingMethod === true && groups.argumentType !== dataTypes.STRING)
mergeSort(that._data, argumentField)
},
_addSkipFields: function _addSkipFields(field) {
this._skipFields[field] = (this._skipFields[field] || 0) + 1
},
_incorrectDataMessage: function() {
if (this._erorrDataSource !== true) {
this._erorrDataSource = true;
this.incidentOccured("E2001")
}
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file themeManager.js */
(function($, DX, undefined) {
var viz = DX.viz,
Palette = viz.core.Palette,
utils = DX.utils;
var HOVER_COLOR_HIGHLIGHTING = 20,
HIGHLIGHTING_STEP = 50;
viz.charts.ThemeManager = viz.core.BaseThemeManager.inherit(function() {
var ctor = function(options, themeGroupName) {
var that = this;
options = options || {};
that._userOptions = options;
that._mergeAxisTitleOptions = [];
themeGroupName && (that._themeSection = themeGroupName);
that._IE8 = DX.browser.msie && DX.browser.version < 9;
that.setTheme(options.theme);
that.palette = new Palette(options.palette, {
stepHighlight: HIGHLIGHTING_STEP,
theme: that._themeName
})
};
var dispose = function() {
var that = this;
that.palette.dispose();
that.palette = that._userOptions = that._mergedSettings = null;
that.callBase()
};
var initDefaultSeriesTheme = function(that) {
var commonSeriesSettings = that._theme.commonSeriesSettings;
commonSeriesSettings.point = commonSeriesSettings.point || {};
commonSeriesSettings.label = commonSeriesSettings.label || {};
that._initializeFont(commonSeriesSettings.label.font)
};
var initAxisTheme = function(that) {
var axisTheme = that._theme.commonAxisSettings;
if (axisTheme) {
axisTheme.label = axisTheme.label || {};
axisTheme.grid = axisTheme.grid || {};
axisTheme.ticks = axisTheme.ticks || {};
axisTheme.line = axisTheme.line || {};
axisTheme.title = axisTheme.title || {};
axisTheme.label.font = axisTheme.label.font || {};
that._initializeFont(axisTheme.label.font);
axisTheme.title.font = axisTheme.title.font || {};
that._initializeFont(axisTheme.title.font)
}
};
var resetPalette = function() {
this.palette.reset()
};
var updatePalette = function(palette) {
this.palette = new Palette(palette || this._theme.defaultPalette, {
stepHighlight: HIGHLIGHTING_STEP,
theme: this.themeName
})
};
var processTitleOptions = function(options) {
return utils.isString(options) ? {text: options} : options
};
var processAxisOptions = function(axisOptions, name) {
if (!axisOptions)
return;
axisOptions = $.extend(true, {}, axisOptions);
axisOptions.title = processTitleOptions(axisOptions.title);
if (axisOptions.type === 'logarithmic' && axisOptions.logarithmBase <= 0 || axisOptions.logarithmBase && !$.isNumeric(axisOptions.logarithmBase)) {
axisOptions.logarithmBase = undefined;
axisOptions.logarithmBaseError = true
}
if (axisOptions.label) {
if (axisOptions.label.alignment)
axisOptions.label['userAlignment'] = true;
if (!axisOptions.label.overlappingBehavior) {
if (axisOptions.label.staggered)
axisOptions.label.overlappingBehavior = {
mode: 'stagger',
staggeringSpacing: axisOptions.label.staggeringSpacing
};
if (axisOptions.label.rotationAngle)
axisOptions.label.overlappingBehavior = {
mode: 'rotate',
rotationAngle: axisOptions.label.rotationAngle
}
}
if (utils.isString(axisOptions.label.overlappingBehavior))
axisOptions.label.overlappingBehavior = {mode: axisOptions.label.overlappingBehavior};
if (!axisOptions.label.overlappingBehavior || !axisOptions.label.overlappingBehavior.mode)
axisOptions.label.overlappingBehavior = axisOptions.label.overlappingBehavior || {}
}
return axisOptions
};
var applyParticularAxisOptions = function(name, userOptions, rotated) {
var theme = this._theme,
position = !(rotated ^ name === "valueAxis") ? "horizontalAxis" : "verticalAxis",
commonAxisSettings = processAxisOptions(this._userOptions["commonAxisSettings"], name);
return $.extend(true, {}, theme.commonAxisSettings, theme[position], theme[name], commonAxisSettings, processAxisOptions(userOptions, name))
};
var mergeOptions = function(name, userOptions) {
userOptions = userOptions || this._userOptions[name];
var theme = this._theme[name],
result = this._mergedSettings[name];
if (result)
return result;
if ($.isPlainObject(theme) && $.isPlainObject(userOptions))
result = $.extend(true, {}, theme, userOptions);
else
result = utils.isDefined(userOptions) ? userOptions : theme;
this._mergedSettings[name] = result;
return result
};
var applyParticularTheme = {
base: mergeOptions,
argumentAxis: applyParticularAxisOptions,
valueAxisRangeSelector: function() {
return mergeOptions.call(this, 'valueAxis')
},
valueAxis: applyParticularAxisOptions,
title: function(name) {
var userOptions = processTitleOptions(this._userOptions[name]);
return mergeOptions.call(this, name, userOptions)
},
series: function(name, userOptions, isPie) {
var theme = this._theme,
userCommonSettings = this._userOptions.commonSeriesSettings || {},
themeCommonSettings = theme.commonSeriesSettings,
type = ((userOptions.type || userCommonSettings.type || themeCommonSettings.type) + '').toLowerCase(),
settings,
palette = this.palette,
isBar = ~type.indexOf('bar'),
isBubble = ~type.indexOf('bubble'),
mainSeriesColor,
containerBackgroundColor = this.getOptions("containerBackgroundColor");
if (isBar || isBubble) {
userOptions = $.extend(true, {}, userCommonSettings, userCommonSettings[type], userOptions);
var seriesVisibility = userOptions.visible;
userCommonSettings = {type: {}};
$.extend(true, userOptions, userOptions.point);
userOptions.visible = seriesVisibility
}
settings = $.extend(true, {}, themeCommonSettings, themeCommonSettings[type], userCommonSettings, userCommonSettings[type], userOptions);
settings.type = type;
settings.containerBackgroundColor = containerBackgroundColor;
if (!isPie) {
settings.widgetType = 'chart';
mainSeriesColor = settings.color || palette.getNextColor()
}
else {
settings.widgetType = 'pieChart';
mainSeriesColor = function() {
return palette.getNextColor()
}
}
settings.mainSeriesColor = mainSeriesColor;
settings._IE8 = this._IE8;
return settings
},
pieSegment: function(name, seriesSettings, segmentSettings) {
var settings = $.extend(true, {}, seriesSettings, segmentSettings);
var mainColor = new DX.Color(settings.color || this.palette.getNextColor());
settings.color = mainColor.toHex();
settings.border.color = settings.border.color || mainColor.toHex();
settings.hoverStyle.color = settings.hoverStyle.color || this._IE8 && mainColor.highlight(HOVER_COLOR_HIGHLIGHTING) || mainColor.toHex();
settings.hoverStyle.border.color = settings.hoverStyle.border.color || mainColor.toHex();
settings.selectionStyle.color = settings.selectionStyle.color || this._IE8 && mainColor.highlight(HOVER_COLOR_HIGHLIGHTING) || mainColor.toHex();
settings.selectionStyle.border.color = settings.selectionStyle.border.color || mainColor.toHex();
return settings
},
animation: function(name) {
var userOptions = this._userOptions[name];
userOptions = $.isPlainObject(userOptions) ? userOptions : utils.isDefined(userOptions) ? {enabled: !!userOptions} : {};
return mergeOptions.call(this, name, userOptions)
}
};
return {
_themeSection: 'chart',
ctor: ctor,
dispose: dispose,
_initializeTheme: function() {
var that = this,
theme = this._theme;
theme.legend = theme.legend || {};
theme.legend.font = theme.legend.font || {};
that._initializeFont(theme.legend.font);
initDefaultSeriesTheme(that);
initAxisTheme(that);
theme.title = theme.title || {};
theme.title.font = theme.title.font || {};
that._initializeFont(theme.title.font);
theme.tooltip = theme.tooltip || {};
theme.tooltip.font = theme.tooltip.font || {};
that._initializeFont(theme.tooltip.font);
theme.loadingIndicator = theme.loadingIndicator || {};
theme.loadingIndicator.font = theme.loadingIndicator.font || {};
that._initializeFont(theme.loadingIndicator.font)
},
resetPalette: resetPalette,
getOptions: function(name) {
return (applyParticularTheme[name] || applyParticularTheme["base"]).apply(this, arguments)
},
setTheme: function(theme) {
var that = this;
that._mergedSettings = {};
that.callBase(theme);
that.getOptions('rtlEnabled') && $.extend(true, that._theme, that._theme._rtl)
},
resetOptions: function(name) {
this._mergedSettings[name] = null
},
update: function(options) {
this._userOptions = options
},
updatePalette: updatePalette
}
}())
})(jQuery, DevExpress);
/*! Module viz-core, file factory.js */
(function($, DX) {
var viz = DX.viz,
charts = viz.charts,
series = charts.series;
charts.factory = function() {
var createSeriesFamily = function(options) {
return new series.SeriesFamily(options)
};
var createAxis = function(renderer, options) {
return new charts.Axis(renderer, options)
};
var createThemeManager = function(options, groupName) {
return new charts.ThemeManager(options, groupName)
};
var createDataValidator = function(data, groups, incidentOccured, dataPrepareOptions) {
return new charts.DataValidator(data, groups, incidentOccured, dataPrepareOptions)
};
var createTracker = function(options) {
return new charts.Tracker(options)
};
var createTitle = function(renderer, canvas, options, group) {
return new charts.ChartTitle(renderer, canvas, options, group)
};
var createChartLayoutManager = function(options) {
return new charts.LayoutManager(options)
};
return {
createSeriesFamily: createSeriesFamily,
createAxis: createAxis,
createThemeManager: createThemeManager,
createDataValidator: createDataValidator,
createTracker: createTracker,
createChartLayoutManager: createChartLayoutManager,
createTitle: createTitle
}
}()
})(jQuery, DevExpress);
/*! Module viz-core, file baseWidget.js */
(function($, DX, undefined) {
var core = DX.viz.core,
utils = DX.utils;
DX.viz.core.BaseWidget = DX.DOMComponent.inherit({
NAMESPACE: DX.ui,
_init: function() {
this._setRedrawOnResize(this._getOptionRedrawOnResize());
this._incidentOccured = this._createIncidentOccured();
this._renderVisiblityChange()
},
_optionChanged: function(name, value, prevValue) {
var that = this;
switch (name) {
case'redrawOnResize':
that._setRedrawOnResize(that._getOptionRedrawOnResize());
break;
case'loadingIndicator':
that._updateLoadIndicator(that._getLoadIndicatorOption());
break;
default:
that._invalidate()
}
that.callBase(name, value, prevValue)
},
_getOptionRedrawOnResize: function() {
var redrawOnResize = this.option('redrawOnResize');
redrawOnResize = redrawOnResize !== undefined ? !!redrawOnResize : true;
return redrawOnResize
},
_getLoadIndicatorOption: function() {
return this.option('loadingIndicator')
},
_dispose: function() {
var that = this;
if (that._resizeHandlerCallback)
that._removeResizeCallbacks();
that._incidentOccured = null;
that.callBase()
},
_visibilityChanged: function(visible) {
if (visible)
this.render()
},
_setRedrawOnResize: function(redrawOnResize) {
var that = this;
if (redrawOnResize) {
if (!that._resizeHandlerCallback && utils.isFunction(that._resize)) {
that._resizeHandlerCallback = DX.utils.createResizeHandler(function() {
that._resize()
});
utils.windowResizeCallbacks.add(that._resizeHandlerCallback)
}
}
else
that._removeResizeCallbacks()
},
_removeResizeCallbacks: function() {
var that = this;
that._resizeHandlerCallback && that._resizeHandlerCallback.stop();
utils.windowResizeCallbacks.remove(that._resizeHandlerCallback);
delete that._resizeHandlerCallback
},
_showLoadIndicator: function(options, canvas) {
var that = this;
that._loadIndicator = this._loadIndicator || core.CoreFactory.createLoadIndicator(options, that._element());
that._loadIndicator.show(canvas.width, canvas.height);
that._initializing && that._loadIndicator.endLoading(undefined, true)
},
_updateLoadIndicator: function(options, width, height) {
this._loadIndicator && this._loadIndicator.applyOptions(options, width, height)
},
_endLoading: function(complete) {
if (this._loadIndicator)
this._loadIndicator.endLoading(complete);
else
complete && complete()
},
_reappendLoadIndicator: function() {
this._loadIndicator && this._loadIndicator.toForeground()
},
_disposeLoadIndicator: function() {
this._loadIndicator && this._loadIndicator.dispose();
this._loadIndicator = null
},
_setDefaultOptions: function() {
this.callBase();
this.option({incidentOccured: function(options) {
var message = "" + options.id + " - " + options.text,
majorVerision = options.version.split(".").slice(0, 2).join("_"),
url = "http://js.devexpress.com/error/" + majorVerision + "/" + options.id;
utils.logger.warn(message + "\n" + url)
}})
},
_createIncidentOccured: function() {
var that = this;
return function(errorOrWarningId, options) {
var isError = errorOrWarningId[0] === 'E',
type = isError ? "error" : "warning",
formattingArray = options ? options.slice(0) : [],
text,
incidentOccuredFunc = that.option('incidentOccured');
formattingArray.unshift(core.errorsWarnings[errorOrWarningId]);
text = utils.stringFormat.apply(null, formattingArray);
if (utils.isFunction(incidentOccuredFunc))
setTimeout(function() {
incidentOccuredFunc({
id: errorOrWarningId,
type: type,
args: options,
text: text,
widget: that.NAME,
version: DevExpress.VERSION
})
})
}
},
_normalizeHtml: function(html) {
var re = /xmlns="[\s\S]*?"/gi,
first = true;
html = html.replace(re, function(match) {
if (!first)
return "";
first = false;
return match
});
return html.replace(/xmlns:NS1="[\s\S]*?"/gi, "").replace(/NS1:xmlns:xlink="([\s\S]*?)"/gi, 'xmlns:xlink="$1"')
},
_drawn: function() {
var that = this,
drawnCallback = that.option('drawn');
utils.isFunction(drawnCallback) && setTimeout(function() {
drawnCallback(that)
})
},
showLoadingIndicator: function() {
this._showLoadIndicator(this.option('loadingIndicator'), this.canvas || {})
},
hideLoadingIndicator: function() {
this._loadIndicator && this._loadIndicator.hide()
},
endUpdate: function() {
if (this._updateLockCount === 1 && !this._requireRefresh)
this.hideLoadingIndicator();
this.callBase()
},
svg: function() {
var renderer = this.renderer || this._renderer;
return renderer ? this._normalizeHtml(renderer.svg()) : ''
}
})
})(jQuery, DevExpress);
/*! Module viz-core, file CoreFactory.js */
(function(DX, undefined) {
var renderers = DX.viz.renderers,
core = DX.viz.core;
DX.viz.core.CoreFactory = function() {
return {
createSeries: function(renderer, options) {
return new core.series.Series(renderer, options)
},
createPoint: function(data, options) {
return new core.series.points.Point(data, options)
},
createLabel: function(type, data, options) {
if (type === "pie" || type === "doughnut" || type === "donut")
return new core.series.points.PieLabel(data, options);
else
return new core.series.points.Label(data, options)
},
createRenderer: function(options) {
return new renderers.Renderer(options)
},
createTranslator1D: function(fromValue, toValue, fromAngle, toAngle) {
return (new core.Translator1D).setDomain(fromValue, toValue).setCodomain(fromAngle, toAngle)
},
createTranslator2D: function(range, canvas, options) {
return new core.Translator2D(range, canvas, options)
},
getTickProvider: function() {
return core.tickProvider
},
createTooltip: function(options, group, renderer) {
return new core.Tooltip(options, group, renderer)
},
createLoadIndicator: function(options, group) {
return new core.LoadIndicator(options, group)
},
createLegend: function(data, options, renderer, group) {
return new core.Legend(data, options, renderer, group)
},
createSeriesFamily: function(options) {
return new core.series.helpers.SeriesFamily(options)
}
}
}()
})(DevExpress);
DevExpress.MOD_VIZ_CORE = true
}
if (!DevExpress.MOD_VIZ_CHARTS) {
if (!DevExpress.MOD_VIZ_CORE)
throw Error('Required module is not referenced: viz-core');
/*! Module viz-charts, file chartTitle.js */
(function($, DX, undefined) {
var isDefined = DX.utils.isDefined,
endsWith = function(value, pattern) {
return value.substr(value.length - pattern.length) === pattern
},
startsWith = function(value, pattern) {
return value.indexOf(pattern) === 0
},
decreaseGaps = DevExpress.viz.core.utils.decreaseGaps,
DEFAULT_MARGIN = 10;
DX.viz.charts.ChartTitle = DX.Class.inherit({
ctor: function(renderer, options, width, group) {
var that = this;
that._init(options, width);
that.renderer = renderer;
that.titleGroup = group
},
dispose: function() {
var that = this;
that.renderer = null;
that.clipRect = null;
that.title = null;
that.innerTitleGroup = null;
that.titleGroup = null;
that.options = null
},
update: function(options, width) {
this._init(options, width)
},
_init: function(options, width) {
var that = this;
if (options) {
that._parseAlignments(options);
that.horizontalAlignment = options.horizontalAlignment;
that.verticalAlignment = options.verticalAlignment;
that._parseMargins(options);
that.margin = options.margin;
that.options = options
}
that.setSize({width: width})
},
_parseMargins: function(options) {
options.margin = isDefined(options.margin) ? options.margin : {};
if (typeof options.margin === 'number') {
options.margin = options.margin >= 0 ? options.margin : DEFAULT_MARGIN;
options.margin = {
top: options.margin,
bottom: options.margin,
left: options.margin,
right: options.margin
}
}
else {
options.margin.top = options.margin.top >= 0 ? options.margin.top : DEFAULT_MARGIN;
options.margin.bottom = options.margin.bottom >= 0 ? options.margin.bottom : DEFAULT_MARGIN;
options.margin.left = options.margin.left >= 0 ? options.margin.left : DEFAULT_MARGIN;
options.margin.right = options.margin.right >= 0 ? options.margin.right : DEFAULT_MARGIN
}
},
_parseAlignments: function(options) {
if (isDefined(options.position) && !(isDefined(options.verticalAlignment) && isDefined(options.horizontalAlignment))) {
options.position = options.position.toLowerCase();
options.verticalAlignment = endsWith(options.position, 'top') ? 'top' : 'bottom';
options.horizontalAlignment = startsWith(options.position, 'left') ? 'left' : startsWith(options.position, 'center') && 'center' || 'right';
return
}
options.verticalAlignment = (options.verticalAlignment || '').toLowerCase();
options.horizontalAlignment = (options.horizontalAlignment || '').toLowerCase();
if (options.verticalAlignment !== 'top' && options.verticalAlignment !== 'bottom')
options.verticalAlignment = 'top';
if (options.horizontalAlignment !== 'left' && options.horizontalAlignment !== 'center' && options.horizontalAlignment !== 'right')
options.horizontalAlignment = 'center'
},
_setBoundingRect: function() {
var that = this,
options = that.options,
margin = that.changedMargin || that.margin,
box;
if (!that.innerTitleGroup)
return;
box = that.innerTitleGroup.getBBox();
box.height += margin.top + margin.bottom;
box.width += margin.left + margin.right;
box.x -= margin.left;
box.y -= margin.top;
if (isDefined(options.placeholderSize))
box.height = options.placeholderSize;
that.boundingRect = box
},
draw: function() {
var that = this,
titleOptions = that.options,
renderer = that.renderer,
attr;
if (!titleOptions.text)
return;
that.changedMargin = null;
if (!that.innerTitleGroup) {
that.innerTitleGroup = renderer.createGroup();
that.clipRect = that.createClipRect();
that.titleGroup && that.clipRect && that.titleGroup.applySettings({clipId: that.clipRect.id})
}
else
that.innerTitleGroup.clear();
that.innerTitleGroup.append(that.titleGroup);
attr = {
font: titleOptions.font,
align: that.horizontalAlignment,
style: titleOptions.fontStyle
};
that.title = renderer.createText(titleOptions.text, 0, 0, attr).append(that.innerTitleGroup);
that.title.text = titleOptions.text;
that._correctTitleLength();
that._setClipRectSettings()
},
_correctTitleLength: function() {
var that = this,
text = that.title.text,
updateText,
lineLength,
box;
that.title.updateText(text);
that._setBoundingRect();
box = that.getLayoutOptions();
if (that._width > box.width || text.indexOf("
") !== -1)
return;
lineLength = text.length * that._width / box.width;
updateText = text.substr(0, ~~lineLength - 1 - 3) + "...";
that.title.updateText(updateText);
that._setBoundingRect()
},
changeSize: function(size) {
var that = this,
margin = $.extend(true, {}, that.margin);
if (margin.top + margin.bottom < size.height) {
if (this.innerTitleGroup) {
that.options._incidentOccured("W2103");
this.innerTitleGroup.remove();
this.innerTitleGroup = null
}
if (that.clipRect) {
that.clipRect.remove();
that.clipRect = null
}
}
else if (size.height > 0) {
decreaseGaps(margin, ["top", "bottom"], size.height);
size.height && (that.changedMargin = margin)
}
that._correctTitleLength();
that._setBoundingRect();
that._setClipRectSettings()
},
getLayoutOptions: function() {
var options = this.options,
boundingRect = this.innerTitleGroup ? this.boundingRect : {
width: 0,
height: 0,
x: 0,
y: 0
};
boundingRect.verticalAlignment = options.verticalAlignment;
boundingRect.horizontalAlignment = options.horizontalAlignment;
boundingRect.cutLayoutSide = options.verticalAlignment;
return boundingRect
},
setSize: function(size) {
this._width = size.width || this._width
},
shift: function(x, y) {
var that = this,
box = that.getLayoutOptions();
x -= box.x;
y -= box.y;
that.innerTitleGroup && that.innerTitleGroup.move(x, y);
that.clipRect && that.clipRect.updateRectangle({
translateX: x,
translateY: y
})
},
createClipRect: function() {
if (isDefined(this.options.placeholderSize))
return this.renderer.createClipRect(0, 0, 0, 0)
},
_setClipRectSettings: function() {
var bbox = this.getLayoutOptions(),
clipRect = this.clipRect;
if (clipRect) {
clipRect.append();
clipRect.updateRectangle({
x: bbox.x,
y: bbox.y,
width: bbox.width,
height: bbox.height
})
}
}
});
DX.viz.charts.ChartTitle.__DEFAULT_MARGIN = DEFAULT_MARGIN
})(jQuery, DevExpress);
/*! Module viz-charts, file axis.js */
(function($, DX, undefined) {
var utils = DX.utils,
isDefinedUtils = utils.isDefined,
isDateUtils = utils.isDate,
mathAbs = Math.abs,
core = DX.viz.core,
AXIS_VALUE_MARGIN_PRIORITY = 100,
DEFAULT_AXIS_LABEL_SPACING = 5,
AXIS_STAGGER_OVERLAPPING_KOEF = 2,
MAX_GRID_BORDER_ADHENSION = 4,
CANVAS_POSITION_PREFIX = 'canvas_position_',
CANVAS_POSITION_START = 'canvas_position_start',
CANVAS_POSITION_END = 'canvas_position_end',
TOP = 'top',
BOTTOM = 'bottom',
LEFT = 'left',
RIGHT = 'right',
CENTER = 'center';
DX.viz.charts.AXIS_STAGGER_OVERLAPPING_KOEF = AXIS_STAGGER_OVERLAPPING_KOEF;
var processCustomOptions = function(options) {
var label = options.label,
position = options.position;
if (options.isHorizontal) {
if (!(position === BOTTOM || position === TOP))
position = BOTTOM
}
else if (!(position === LEFT || position === RIGHT))
position = LEFT;
options.position = position;
if (position === RIGHT && !label.userAlignment)
label.alignment = LEFT
};
var formatLabel = function(value, options, axisMinMax) {
var formatObject = {
value: value,
valueText: DX.formatHelper.format(value, options.format, options.precision) || ''
};
if (axisMinMax) {
formatObject.min = axisMinMax.min;
formatObject.max = axisMinMax.max
}
return options.customizeText ? options.customizeText.call(formatObject, formatObject) : formatObject.valueText
};
var nextState = function(state) {
switch (state) {
case'overlap':
return 'stagger';
case'stagger':
return 'rotate';
case'rotate':
default:
return 'end'
}
};
DX.viz.charts.Axis = function(renderer, options) {
var debug = DX.utils.debug;
debug.assertParam(renderer, 'renderer was not passed');
debug.assertParam(options.label, 'label was not passed');
debug.assertParam(options.tick, 'tick was not passed');
debug.assertParam(options.grid, 'grid was not passed');
debug.assertParam(options.title, 'title was not passed');
debug.assert(options.axisDivisionFactor, 'axisDivisionFactor was not passed');
debug.assert(options.stripStyle, 'stripStyle was not passed');
debug.assert(options.constantLineStyle, 'constantLineStyle was not passed');
debug.assert(options.position, 'position was not passed');
debug.assertParam(options.isHorizontal, 'isHorizontal was not passed');
this.renderer = renderer;
this._init(options)
};
$.extend(DX.viz.charts.Axis.prototype, {
dispose: function() {
var that = this;
that._axisElementsGroup && that._axisElementsGroup.dispose();
$.each(that.labels || [], function(_, label) {
label.removeData()
});
that.labels = null;
that.title = null;
that.stripLabels = null;
that.stripRects = null;
that.constantLineLabels = null;
that.constantLines = null;
that._axisStripGroup = null;
that._axisConstantLineGroup = null;
that._axisLableGroup = null;
that._axisLineGroup = null;
that._axisElementsGroup = null;
that._axisGridGroup = null;
that._axisGroup = null;
that.axesContainerGroup = null;
that.stripsGroup = null;
that.constantLinesGroup = null;
that._axisTitleGroup = null;
that.renderer = null;
that.translator = null;
that.orthogonalTranslator = null;
that.options = null;
that.textOptions = null;
that._tickValues = null;
that._fullTickValues = null;
that._fullTickPositions = null
},
_init: function(options) {
var that = this,
categories = options.categories,
labelOptions = options.label;
options.hoverMode = options.hoverMode ? options.hoverMode.toLowerCase() : 'none';
that.hasLabelFormat = labelOptions.format !== '' && isDefinedUtils(labelOptions.format);
that.options = options;
that.staggered = labelOptions.staggered;
labelOptions.minSpacing = isDefinedUtils(labelOptions.minSpacing) ? labelOptions.minSpacing : DEFAULT_AXIS_LABEL_SPACING;
processCustomOptions(options);
if (categories) {
that.labelsNumber = categories.length;
that.ticksNumber = that.labelsNumber
}
options.range = {
min: options.min,
max: options.max,
categories: options.categories && options.categories.slice(0)
};
that.pane = options.pane;
that.textOptions = {
align: labelOptions.alignment,
font: labelOptions.font,
opacity: labelOptions.opacity,
style: labelOptions.style
};
if (options.type === 'logarithmic') {
if (options.logarithmBaseError) {
options.incidentOccured('E2104');
delete options.logarithmBaseError
}
that.calcInterval = function(value, prevValue) {
return utils.getLog(value / prevValue, options.logarithmBase)
}
}
},
updateSize: function(clearAxis) {
var that = this,
options = that.options,
direction = options.isHorizontal ? "horizontal" : "vertical";
if (that.title && that._axisTitleGroup) {
options.incidentOccured('W2105', [direction]);
that._axisTitleGroup.remove();
that._axisTitleGroup = null
}
if (clearAxis && that._axisElementsGroup && that.labels) {
options.incidentOccured('W2106', [direction]);
that._axisElementsGroup.remove();
that._axisElementsGroup = null
}
that._setBoundingRect()
},
_updateTranslatorInterval: function() {
var that = this,
i,
tickValues,
businessRange = that.translator.getBusinessRange();
if (businessRange && businessRange.addRange && !that.options.categories) {
tickValues = that.getTickValues();
for (i = 0; i < tickValues.length - 1; i++)
businessRange.addRange({interval: mathAbs(tickValues[i] - tickValues[i + 1])})
}
},
setTranslator: function(translator, orthogonalTranslator) {
var that = this;
var debug = DX.utils.debug;
debug.assertParam(translator, 'translator was not passed');
that.translator = translator;
orthogonalTranslator && (that.orthogonalTranslator = orthogonalTranslator);
that.resetTicks();
that._updateTranslatorInterval()
},
resetTicks: function() {
var that = this;
that._tickValues = that._tickPositions = that._fullTickValues = that._fullTickPositions = null
},
setRange: function(range) {
var debug = DX.utils.debug;
debug.assertParam(range, 'range was not passed');
var options = this.options;
options.min = range.minVisible;
options.max = range.maxVisible;
options.categories = range.categories;
options.stubData = range.stubData;
this.resetTicks()
},
_drawAxis: function() {
var that = this,
translator = that.translator,
options = that.options,
hasCategories = !!options.categories,
axisPosition = that.axisPosition,
p11,
p12,
p21,
p22;
if (!options.visible)
return;
p11 = translator.translateSpecialCase(CANVAS_POSITION_START);
p21 = translator.translateSpecialCase(CANVAS_POSITION_END);
if (options.isHorizontal)
p12 = p22 = axisPosition;
else {
p12 = p11;
p22 = p21;
p11 = p21 = axisPosition
}
that.renderer.createLine(p11, p12, p21, p22, {
strokeWidth: options.width,
stroke: options.color,
strokeOpacity: options.opacity
}).append(that._axisLineGroup)
},
_getOptimalRotationAngle: function(tick1, tick2, labelOptions) {
var that = this,
translator = that.options.isHorizontal ? that.translator : that.orthogonalTranslator,
renderer = that.renderer,
outOfScreen = core.outOfScreen,
textOptions = that.textOptions,
svgElement1 = renderer.createText(formatLabel(tick1, labelOptions), outOfScreen.x + translator.translate(tick1), outOfScreen.y, textOptions).append(),
svgElement2 = renderer.createText(formatLabel(tick2, labelOptions), outOfScreen.x + translator.translate(tick2), outOfScreen.y, textOptions).append(),
bBox1 = svgElement1.getBBox(),
bBox2 = svgElement2.getBBox(),
angle = Math.asin((bBox1.height + labelOptions.minSpacing) / (bBox2.x - bBox1.x)) * 180 / Math.PI;
svgElement1.remove();
svgElement2.remove();
return isNaN(angle) ? 90 : Math.ceil(angle)
},
_applyOptimalOverlappingBehavior: function(ticks, ticksOptions) {
var that = this,
overlappingBehavior = that.overlappingBehavior,
isOverlapped = false,
rotationAngle = null,
mode = null,
options = $.extend({}, ticksOptions),
state = 'overlap';
while (state !== 'end') {
isOverlapped = rotationAngle && rotationAngle !== 90 ? false : that.options.tickProvider.isOverlappedTicks(ticks, options);
state = nextState(isOverlapped ? state : null);
that.testAutoOverlappingState = state;
switch (state) {
case'stagger':
options.screenDelta *= AXIS_STAGGER_OVERLAPPING_KOEF;
mode = state;
break;
case'rotate':
rotationAngle = that._getOptimalRotationAngle(ticks[0], ticks[1], that.options.label);
that.testAutoOverlappingRotationAngle = rotationAngle;
options.screenDelta = ticksOptions.screenDelta;
options.textOptions.rotate = rotationAngle;
mode = state;
break
}
}
that.testAutoOverlappingOptions = options;
overlappingBehavior.isOverlapped = isOverlapped;
overlappingBehavior.mode = mode;
overlappingBehavior.rotationAngle = rotationAngle
},
_getTicksOptions: function() {
var that = this,
options = that.options,
translator = that.translator,
screenDelta = mathAbs(translator.translateSpecialCase(CANVAS_POSITION_START) - translator.translateSpecialCase(CANVAS_POSITION_END)),
min = options.min,
max = options.max,
digitPosition = utils.getSignificantDigitPosition(mathAbs(max - min) / screenDelta),
correctingValue,
getText = function() {
return ''
};
if (utils.isNumber(min) && options.type !== 'logarithmic') {
min = utils.roundValue(options.min, digitPosition);
if (min < options.min) {
correctingValue = Math.pow(10, -digitPosition);
min = utils.applyPrecisionByMinDelta(min, correctingValue, min + correctingValue)
}
if (min > max)
min = options.min
}
if (!options.stubData)
getText = function(value) {
return formatLabel(value, options.label, {
min: min,
max: max
})
};
return {
min: min,
max: max,
base: options.type === 'logarithmic' ? options.logarithmBase : undefined,
axisType: options.type,
dataType: options.dataType,
customTicks: $.isArray(options.categories) ? options.categories : that._tickValues,
useTicksAutoArrangement: false,
textOptions: that.textOptions,
getText: getText,
renderer: that.renderer,
textSpacing: options.label.minSpacing,
translator: translator,
tickInterval: options.stubData ? null : options.tickInterval,
screenDelta: screenDelta,
gridSpacingFactor: options.axisDivisionFactor,
isHorizontal: options.isHorizontal,
setTicksAtUnitBeginning: options.setTicksAtUnitBeginning,
incidentOccured: options.incidentOccured
}
},
getTickValues: function() {
var that = this,
correctedScreenDelta,
options = that.options,
tickProvider = options.tickProvider,
labelOptions = options.label,
categories = options.categories,
ticksOptions = that._getTicksOptions();
that._fullTickValues = that._tickValues = tickProvider.getTicks(ticksOptions);
if ((isDateUtils(options.min) || isDateUtils(categories && categories[0])) && !that.hasLabelFormat && that._tickValues.length)
labelOptions.format = DX.formatHelper.getDateFormatByTicks(that._tickValues);
that.overlappingBehavior = labelOptions.overlappingBehavior ? $.extend({}, labelOptions.overlappingBehavior) : null;
if (that.overlappingBehavior) {
if (!options.isHorizontal && that.overlappingBehavior.mode !== 'ignore')
that.overlappingBehavior.mode = 'enlargeTickInterval';
ticksOptions.useTicksAutoArrangement = that.overlappingBehavior.mode !== 'ignore';
if (ticksOptions.useTicksAutoArrangement)
that._fullTickValues = that._tickValues = tickProvider.getCorrectedTicks(that._fullTickValues, ticksOptions);
if (that.overlappingBehavior.mode === 'auto') {
that.textOptions.rotate = 0;
that._applyOptimalOverlappingBehavior(that._fullTickValues, ticksOptions);
ticksOptions.useTicksAutoArrangement = that.overlappingBehavior.isOverlapped
}
if (that.overlappingBehavior.mode === 'rotate') {
that.textOptions.rotate = that.overlappingBehavior.rotationAngle;
if (!labelOptions.userAlignment)
that.textOptions.align = LEFT
}
else if (!labelOptions.userAlignment)
that.textOptions.align = labelOptions.alignment
}
if (ticksOptions.useTicksAutoArrangement) {
correctedScreenDelta = that._tickValues.length ? that.translator.translate(that._tickValues[that._tickValues.length - 1]) - that.translator.translate(that._tickValues[0]) : null;
if (correctedScreenDelta) {
ticksOptions.screenDelta = mathAbs(correctedScreenDelta);
ticksOptions.ticksCount = that._tickValues.length - 1
}
else
ticksOptions.ticksCount = that._tickValues.length;
if (that.overlappingBehavior && that.overlappingBehavior.mode === 'stagger')
ticksOptions.screenDelta *= AXIS_STAGGER_OVERLAPPING_KOEF;
ticksOptions.customTicks = that._tickValues;
that._tickValues = tickProvider.getTicks(ticksOptions)
}
that._testTKScreenDelta = ticksOptions.screenDelta;
that._autoArrangementStep = that._tickValues.autoArrangementStep;
that._useTicksAutoArrangement = ticksOptions.useTicksAutoArrangement;
if (that.options.stubData) {
that._testSkippedFormattingAndOverlapping = true;
return that._tickValues
}
if (!$.isArray(categories))
that._fullTickValues = that._tickValues;
return that._tickValues
},
setTickValues: function(tickValues) {
this.resetTicks();
this._fullTickValues = this._tickValues = tickValues
},
_prepareLabelsToDraw: function() {
var that = this,
ticksValues = that.getTickValues(),
ticks = [],
i;
if (ticksValues.hideLabels || that.options.stubData)
ticks.hideLabels = true;
for (i = 0; i < ticksValues.length; i++)
ticks.push({
text: ticksValues[i],
pos: that.translator.translate(ticksValues[i])
});
return ticks
},
_correctTicksPosition: function(ticks) {
var that = this,
options = that.options,
tickDelta = that.translator.getInterval() / 2,
i;
if (options.categories && (options.discreteAxisDivisionMode !== 'crossLabels' || !options.discreteAxisDivisionMode)) {
if (options.isHorizontal) {
if (!options.valueMarginsEnabled)
ticks = ticks.slice(0, ticks.length - 1)
}
else {
tickDelta = -tickDelta;
if (!options.valueMarginsEnabled)
ticks = ticks.slice(1, ticks.length)
}
for (i = 0; i < ticks.length; i++)
ticks[i].pos = ticks[i].pos + tickDelta
}
return ticks
},
_prepareFullTicksToDraw: function() {
var that = this,
ticksValues = that._fullTickValues,
ticks = [],
i;
if (!that._fullTickPositions) {
if (!ticksValues) {
that.getTickValues();
ticksValues = that._fullTickValues || []
}
for (i = 0; i < ticksValues.length; i++)
ticks.push({pos: that.translator.translate(ticksValues[i])});
that._fullTickPositions = that._correctTicksPosition(ticks)
}
return that._fullTickPositions
},
_drawTicks: function() {
var that = this,
options = that.options,
ticksOptions = options.tick,
i,
axisPosition = that.axisPosition,
tickStart = axisPosition - 4,
tickEnd = axisPosition + 4,
tick,
ticksToDraw;
if (!ticksOptions.visible)
return;
var drawLine = function(p11, p12, p21, p22) {
that.renderer.createLine(p11, p12, p21, p22, {
strokeWidth: 1,
stroke: ticksOptions.color,
strokeOpacity: ticksOptions.opacity
}).append(that._axisLineGroup)
};
ticksToDraw = that._prepareFullTicksToDraw();
if (options.isHorizontal)
for (i = 0; i < ticksToDraw.length; i++) {
tick = ticksToDraw[i];
drawLine(tick.pos, tickStart, tick.pos, tickEnd)
}
else
for (i = 0; i < ticksToDraw.length; i++) {
tick = ticksToDraw[i];
drawLine(tickStart, tick.pos, tickEnd, tick.pos)
}
},
setPercentLabelFormat: function() {
var labelOptions = this.options.label;
if (!this.hasLabelFormat)
labelOptions.format = 'percent'
},
resetAutoLabelFormat: function() {
var labelOptions = this.options.label;
if (!this.hasLabelFormat)
delete labelOptions.format
},
_drawLabels: function() {
var that = this,
i,
options = that.options,
renderer = that.renderer,
axisPosition = that.axisPosition,
labelOptions = options.label,
labelOffset = labelOptions.indentFromAxis,
labelsToDraw,
labelPoint,
label,
labels = [],
createText = options.isHorizontal ? renderer.createText : function(text, y, x, textOptions) {
return this.createText(text, x, y, textOptions)
},
emptyStrRegExp = /^\s+$/,
currentLabelConst = options.position === TOP || options.position === LEFT ? axisPosition - labelOffset : axisPosition + labelOffset,
text;
if (!labelOptions.visible || !that._axisElementsGroup)
return;
labelsToDraw = that._prepareLabelsToDraw();
if (labelsToDraw.length === 0 || labelsToDraw.hideLabels)
return true;
for (i = 0; i < labelsToDraw.length; i++) {
labelPoint = labelsToDraw[i];
text = formatLabel(labelPoint.text, labelOptions, {
min: options.min,
max: options.max
});
if (isDefinedUtils(text) && text !== '' && !emptyStrRegExp.test(text)) {
label = createText.call(renderer, text, labelPoint.pos, currentLabelConst, that.textOptions);
labels.push(label);
label.append(that._axisElementsGroup);
label.data({argument: labelPoint.text})
}
}
that.labels = labels
},
getMultipleAxesSpacing: function() {
return this.options.multipleAxesSpacing || 0
},
_drawTitle: function() {
var that = this,
i,
options = that.options,
renderer = that.renderer,
axisPosition = that.axisPosition,
titleOptions = options.title,
title,
attr = {
font: titleOptions.font,
opacity: titleOptions.opacity,
align: CENTER,
'class': 'dx-chart-axis-title'
},
centerPosition = that.translator.translateSpecialCase(CANVAS_POSITION_PREFIX + CENTER),
x,
y;
if (!titleOptions.text || !that._axisTitleGroup)
return;
if (options.isHorizontal) {
x = centerPosition;
y = axisPosition
}
else {
if (options.position === LEFT)
attr.rotate = 270;
else
attr.rotate = 90;
x = axisPosition;
y = centerPosition
}
that.title = renderer.createText(titleOptions.text, x, y, attr).append(that._axisTitleGroup)
},
_drawGrid: function(borderOptions) {
var that = this,
positionsToDraw,
options = that.options,
gridOptions = options.grid,
i;
if (!gridOptions.visible)
return;
borderOptions = borderOptions || {visible: false};
var drawLine = function() {
var translator = that.translator,
orthogonalTranslator = that.orthogonalTranslator,
isHorizontal = options.isHorizontal,
canvasStart = isHorizontal ? LEFT : TOP,
canvasEnd = isHorizontal ? RIGHT : BOTTOM,
positionFrom = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_START),
positionTo = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_END),
firstBorderLinePosition = borderOptions.visible && borderOptions[canvasStart] ? translator.translateSpecialCase(CANVAS_POSITION_PREFIX + canvasStart) : undefined,
lastBorderLinePosition = borderOptions.visible && borderOptions[canvasEnd] ? translator.translateSpecialCase(CANVAS_POSITION_PREFIX + canvasEnd) : undefined;
return function(tick) {
if (mathAbs(tick.pos - firstBorderLinePosition) < MAX_GRID_BORDER_ADHENSION || mathAbs(tick.pos - lastBorderLinePosition) < MAX_GRID_BORDER_ADHENSION)
return;
var p11 = tick.pos,
p12 = positionFrom,
p21 = tick.pos,
p22 = positionTo;
if (!isHorizontal) {
p11 = positionFrom;
p12 = p22 = tick.pos;
p21 = positionTo
}
that.renderer.createLine(p11, p12, p21, p22, {
strokeWidth: gridOptions.width,
stroke: gridOptions.color,
strokeOpacity: gridOptions.opacity
}).append(that._axisGridGroup)
}
}();
positionsToDraw = that._prepareFullTicksToDraw();
for (i = 0; i < positionsToDraw.length; i++)
drawLine(positionsToDraw[i])
},
_drawConstantLine: function() {
var that = this,
group = that._axisConstantLineGroup,
renderer = that.renderer,
options = that.options,
data = options.constantLines,
translator = that.translator,
orthogonalTranslator = that.orthogonalTranslator,
isHorizontal = options.isHorizontal,
i,
lines = [],
labels = [],
positionFrom = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_START),
positionTo = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_END),
canvasStart = translator.translateSpecialCase(CANVAS_POSITION_START),
canvasEnd = translator.translateSpecialCase(CANVAS_POSITION_END),
range = translator.getBusinessRange();
var getPos = function(lineValue) {
var parsedValue = that.validateUnit(lineValue, "E2105", 'constantLine'),
value = translator.translate(parsedValue),
isContinous = !!(range.minVisible || range.maxVisible);
if (!isContinous && $.inArray(lineValue, range.categories || []) === -1 || !isDefinedUtils(value) || value < Math.min(canvasStart, canvasEnd) || value > Math.max(canvasStart, canvasEnd))
return {};
return {
value: value,
parsedValue: parsedValue
}
};
var drawLinesAndLabels = function(lineOptions) {
if (lineOptions.value === undefined)
return;
var pos = getPos(lineOptions.value),
labelOptions = lineOptions.label || {},
value = pos.value,
line,
attr = {
stroke: lineOptions.color,
strokeWidth: lineOptions.width,
dashStyle: lineOptions.dashStyle
};
if (!isDefinedUtils(value)) {
lines.push(null);
if (labelOptions.visible)
labels.push(null);
return
}
line = isHorizontal ? renderer.createLine(value, positionTo, value, positionFrom, attr) : renderer.createLine(positionFrom, value, positionTo, value, attr);
lines.push(line.append(group));
if (labelOptions.visible)
labels.push(that._drawConstantLineLabels(pos.parsedValue, labelOptions, value, group));
else
labels.push(null)
};
for (i = 0; i < data.length; i++)
drawLinesAndLabels(data[i]);
that.constantLines = lines;
that.constantLineLabels = labels
},
_checkAlignmentConstantLineLabels: function(labelOptions) {
var options = this.options;
labelOptions.verticalAlignment = (labelOptions.verticalAlignment || '').toLowerCase();
labelOptions.horizontalAlignment = (labelOptions.horizontalAlignment || '').toLowerCase();
if (options.isHorizontal && labelOptions.position === 'outside') {
labelOptions.verticalAlignment = labelOptions.verticalAlignment === BOTTOM ? BOTTOM : TOP;
labelOptions.horizontalAlignment = CENTER
}
if (options.isHorizontal && labelOptions.position === 'inside') {
labelOptions.verticalAlignment = labelOptions.verticalAlignment === CENTER ? CENTER : labelOptions.verticalAlignment === BOTTOM ? BOTTOM : TOP;
labelOptions.horizontalAlignment = labelOptions.horizontalAlignment === LEFT ? LEFT : RIGHT
}
if (!options.isHorizontal && labelOptions.position === 'outside') {
labelOptions.verticalAlignment = CENTER;
labelOptions.horizontalAlignment = labelOptions.horizontalAlignment === LEFT ? LEFT : RIGHT
}
if (!options.isHorizontal && labelOptions.position === 'inside') {
labelOptions.verticalAlignment = labelOptions.verticalAlignment === BOTTOM ? BOTTOM : TOP;
labelOptions.horizontalAlignment = labelOptions.horizontalAlignment === RIGHT ? RIGHT : labelOptions.horizontalAlignment === CENTER ? CENTER : LEFT
}
},
_drawConstantLineLabels: function(parsedValue, lineLabelOptions, value, group) {
var that = this,
text = lineLabelOptions.text,
orthogonalTranslator = that.orthogonalTranslator,
options = that.options,
labelOptions = options.label,
attr = {
align: CENTER,
font: $.extend({}, labelOptions.font, lineLabelOptions.font)
},
x,
y;
that._checkAlignmentConstantLineLabels(lineLabelOptions);
text = isDefinedUtils(text) ? text : formatLabel(parsedValue, labelOptions);
if (options.isHorizontal) {
x = value;
switch (lineLabelOptions.horizontalAlignment) {
case LEFT:
attr.align = RIGHT;
break;
case RIGHT:
attr.align = LEFT;
break
}
y = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + lineLabelOptions.verticalAlignment)
}
else {
y = value;
x = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + lineLabelOptions.horizontalAlignment);
switch (lineLabelOptions.horizontalAlignment) {
case LEFT:
attr.align = lineLabelOptions.position === 'inside' ? LEFT : RIGHT;
break;
case CENTER:
attr.align = CENTER;
break;
case RIGHT:
attr.align = lineLabelOptions.position === 'inside' ? RIGHT : LEFT;
break
}
}
return that.renderer.createText(text, x, y, attr).append(group)
},
_adjustConstantLineLabels: function() {
var that = this,
options = that.options,
isHorizontal = options.isHorizontal,
lines = that.constantLines,
labels = that.constantLineLabels,
label,
line,
lineBox,
linesOptions,
labelOptions,
box,
x,
y,
i,
padding = isHorizontal ? {
top: 0,
bottom: 0
} : {
left: 0,
right: 0
};
if (labels === undefined && lines === undefined)
return;
for (i = 0; i < labels.length; i++) {
x = y = 0;
linesOptions = options.constantLines[i];
labelOptions = linesOptions.label;
label = labels[i];
if (label !== null) {
line = lines[i];
box = label.getBBox();
lineBox = line.getBBox();
if (isHorizontal)
if (labelOptions.position === 'inside') {
switch (labelOptions.horizontalAlignment) {
case LEFT:
x -= linesOptions.paddingLeftRight;
break;
default:
x += linesOptions.paddingLeftRight;
break
}
switch (labelOptions.verticalAlignment) {
case CENTER:
y += lineBox.y + lineBox.height / 2 - box.y - box.height / 2;
break;
case BOTTOM:
y -= linesOptions.paddingTopBottom;
break;
default:
y += linesOptions.paddingTopBottom + box.height;
break
}
}
else
switch (labelOptions.verticalAlignment) {
case BOTTOM:
y += box.height + linesOptions.paddingTopBottom - (box.y + box.height - that.orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + labelOptions.verticalAlignment));
if (padding[BOTTOM] < box.height + linesOptions.paddingTopBottom)
padding[BOTTOM] = box.height + linesOptions.paddingTopBottom;
break;
default:
y -= linesOptions.paddingTopBottom;
if (padding[TOP] < linesOptions.paddingTopBottom + box.height)
padding[TOP] = linesOptions.paddingTopBottom + box.height;
break
}
else if (labelOptions.position === 'inside') {
switch (labelOptions.horizontalAlignment) {
case CENTER:
x += lineBox.x + lineBox.width / 2 - box.x - box.width / 2;
break;
case RIGHT:
x -= linesOptions.paddingLeftRight;
break;
default:
x += linesOptions.paddingLeftRight;
break
}
switch (labelOptions.verticalAlignment) {
case BOTTOM:
y += lineBox.y - box.y + linesOptions.paddingTopBottom;
break;
default:
y -= linesOptions.paddingTopBottom;
break
}
}
else {
y += lineBox.y + lineBox.height / 2 - box.y - box.height / 2;
switch (labelOptions.horizontalAlignment) {
case RIGHT:
x += linesOptions.paddingLeftRight;
if (padding[RIGHT] < linesOptions.paddingLeftRight + box.width)
padding[RIGHT] = linesOptions.paddingLeftRight + box.width;
break;
default:
x -= linesOptions.paddingLeftRight;
if (padding[LEFT] < linesOptions.paddingLeftRight + box.width)
padding[LEFT] = linesOptions.paddingLeftRight + box.width;
break
}
}
label.move(x, y)
}
}
that.padding = padding
},
_drawStrip: function() {
var that = this,
renderer = that.renderer,
options = that.options,
stripData = options.strips,
translator = that.translator,
orthogonalTranslator = that.orthogonalTranslator,
range = translator.getBusinessRange(),
i,
stripLabels = [],
stripRects = [],
rect,
isHorizontal = options.isHorizontal,
stripOptions,
positionFrom,
positionTo,
stripPos,
stripLabelOptions,
attr;
if (options.stubData)
return;
var getPos = function(startV, endV) {
var isContinous = !!(range.minVisible || range.maxVisible),
cateories = range.categories || [],
start = translator.translate(that.validateUnit(startV, "E2105", "strip")),
end = translator.translate(that.validateUnit(endV, "E2105", "strip")),
canvasStart = translator.translateSpecialCase(CANVAS_POSITION_START),
canvasEnd = translator.translateSpecialCase(CANVAS_POSITION_END),
min = range.minVisible;
if (!isContinous && ($.inArray(startV, cateories) === -1 || $.inArray(endV, cateories) === -1))
return {
stripFrom: 0,
stripTo: 0
};
if (!isDefinedUtils(start) && isContinous)
start = startV < min ? canvasStart : canvasEnd;
if (!isDefinedUtils(end) && isContinous)
end = endV < min ? canvasStart : canvasEnd;
return start < end ? {
stripFrom: start,
stripTo: end
} : {
stripFrom: end,
stripTo: start
}
};
positionFrom = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_START);
positionTo = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_END);
for (i = 0; i < stripData.length; i++) {
stripOptions = stripData[i];
stripLabelOptions = stripOptions.label || {};
attr = {fill: stripOptions.color};
if (stripOptions.startValue !== undefined && stripOptions.endValue !== undefined && stripOptions.color !== undefined) {
stripPos = getPos(stripOptions.startValue, stripOptions.endValue);
if (stripPos.stripTo - stripPos.stripFrom === 0 || !stripPos.stripTo && stripPos.stripTo !== 0 || !stripPos.stripFrom && stripPos.stripFrom !== 0) {
stripRects.push(null);
if (stripLabelOptions.text)
stripLabels.push(null);
continue
}
rect = isHorizontal ? renderer.createRect(stripPos.stripFrom, Math.min(positionFrom, positionTo), stripPos.stripTo - stripPos.stripFrom, mathAbs(positionFrom - positionTo), 0, attr) : renderer.createRect(Math.min(positionFrom, positionTo), stripPos.stripFrom, mathAbs(positionFrom - positionTo), stripPos.stripTo - stripPos.stripFrom, 0, attr);
stripRects.push(rect.append(that._axisStripGroup));
if (stripLabelOptions.text)
stripLabels.push(that._drawStripLabel(stripLabelOptions, stripPos.stripFrom, stripPos.stripTo));
else
stripLabels.push(null)
}
}
that.stripLabels = stripLabels;
that.stripRects = stripRects
},
_drawStripLabel: function(stripLabelOptions, stripFrom, stripTo) {
var that = this,
orthogonalTranslator = that.orthogonalTranslator,
options = that.options,
isHorizontal = options.isHorizontal,
attr = {
align: isHorizontal ? CENTER : LEFT,
font: $.extend({}, options.label.font, stripLabelOptions.font)
},
x,
y;
if (isHorizontal) {
if (stripLabelOptions.horizontalAlignment === CENTER) {
x = stripFrom + (stripTo - stripFrom) / 2;
attr.align = CENTER
}
else if (stripLabelOptions.horizontalAlignment === LEFT) {
x = stripFrom;
attr.align = LEFT
}
else if (stripLabelOptions.horizontalAlignment === RIGHT) {
x = stripTo;
attr.align = RIGHT
}
y = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + stripLabelOptions.verticalAlignment)
}
else {
x = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + stripLabelOptions.horizontalAlignment);
attr.align = stripLabelOptions.horizontalAlignment;
if (stripLabelOptions.verticalAlignment === TOP)
y = stripFrom;
else if (stripLabelOptions.verticalAlignment === CENTER)
y = stripTo + (stripFrom - stripTo) / 2;
else if (stripLabelOptions.verticalAlignment === BOTTOM)
y = stripTo
}
return that.renderer.createText(stripLabelOptions.text, x, y, attr).append(that._axisLableGroup)
},
_initAxisPositions: function() {
var that = this,
position = that.options.position,
delta = 0;
if (that.delta)
delta = that.delta[position] || 0;
that.axisPosition = that.orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + position) + delta
},
_adjustLabels: function() {
var that = this,
options = that.options,
isHorizontal = options.isHorizontal,
position = options.position,
labels = that.labels,
label,
labelHeight,
isNeedLabelAdjustment,
staggeringSpacing,
i,
xt,
shift = that.padding && that.padding[position] || 0,
boxAxis = that._axisElementsGroup && that._axisElementsGroup.getBBox() || {},
box;
if (!options.label.visible || !labels || !labels.length)
return;
for (i = 0; i < labels.length; i++) {
label = labels[i];
box = label.getBBox();
if (isHorizontal && position === BOTTOM)
label.applySettings({y: 2 * label.settings.y - box.y + shift});
else if (!isHorizontal) {
if (position === LEFT)
if (that.textOptions.align === RIGHT)
xt = box.x + box.width - shift;
else if (that.textOptions.align === CENTER)
xt = box.x + box.width / 2 - shift - (boxAxis.width / 2 || 0);
else
xt = box.x - shift - (boxAxis.width || 0);
else if (that.textOptions.align === CENTER)
xt = box.x + box.width / 2 + (boxAxis.width / 2 || 0) + shift;
else if (that.textOptions.align === RIGHT)
xt = box.x + box.width + (boxAxis.width || 0) + shift;
else
xt = box.x + shift;
label.applySettings({
x: xt,
y: label.settings.y + ~~(label.settings.y - box.y - box.height / 2)
})
}
else if (isHorizontal && position === TOP)
label.applySettings({y: 2 * label.settings.y - box.y - box.height - shift})
}
isNeedLabelAdjustment = isHorizontal && that.overlappingBehavior && that.overlappingBehavior.mode === 'stagger';
that._testIsNeedLabelAdjustment = isNeedLabelAdjustment;
if (isNeedLabelAdjustment) {
labelHeight = 0;
for (i = 0; i < labels.length; i = i + 2) {
label = labels[i];
box = label.getBBox();
if (box.height > labelHeight)
labelHeight = box.height
}
staggeringSpacing = that.overlappingBehavior.staggeringSpacing;
that._testStaggeringSpacing = staggeringSpacing;
labelHeight = Math.round(labelHeight) + staggeringSpacing;
for (i = 1; i < labels.length; i = i + 2) {
label = labels[i];
if (position === BOTTOM)
label.move(0, labelHeight);
else if (position === TOP)
label.move(0, -labelHeight)
}
for (i = 0; i < labels.length; i++)
labels[i].rotate(0)
}
},
_adjustStripLabels: function() {
var that = this,
labelOptions,
labels = that.stripLabels,
rects = that.stripRects,
label,
i,
box,
rectBox,
stripOptions,
x,
y;
if (labels === undefined && rects === undefined)
return;
for (i = 0; i < labels.length; i++) {
x = y = 0;
stripOptions = that.options.strips[i];
labelOptions = stripOptions.label;
label = labels[i];
if (label !== null) {
box = label.getBBox();
rectBox = rects[i].getBBox();
if (labelOptions.horizontalAlignment === LEFT)
x += stripOptions.paddingLeftRight;
else if (labelOptions.horizontalAlignment === RIGHT)
x -= stripOptions.paddingLeftRight;
if (labelOptions.verticalAlignment === TOP)
y += rectBox.y - box.y + stripOptions.paddingTopBottom;
else if (labelOptions.verticalAlignment === CENTER)
y += rectBox.y + rectBox.height / 2 - box.y - box.height / 2;
else if (labelOptions.verticalAlignment === BOTTOM)
y -= stripOptions.paddingTopBottom;
label.move(x, y)
}
}
},
_adjustTitle: function() {
var that = this,
options = that.options,
position = options.position,
title = that.title,
margin = options.title.margin,
boxGroup,
boxTitle;
if (!title || !that._axisElementsGroup)
return;
boxTitle = title.getBBox();
boxGroup = that._axisElementsGroup.getBBox();
if (options.isHorizontal)
if (position === BOTTOM)
title.applySettings({
y: boxGroup.isEmpty ? undefined : boxGroup.y + boxGroup.height,
translateY: margin + boxTitle.height
});
else
title.applySettings({
y: boxGroup.isEmpty ? undefined : boxGroup.y,
translateY: -margin
});
else if (position === LEFT)
title.applySettings({
x: boxGroup.isEmpty ? undefined : boxGroup.x,
translateX: -margin
});
else
title.applySettings({
x: boxGroup.isEmpty ? undefined : boxGroup.x + boxGroup.width,
translateX: margin
})
},
draw: function(externalOptions, adjustAxis) {
var that = this,
options = that.options,
isHorizontal = options.isHorizontal,
cssClass = isHorizontal ? 'dxc-h-axis' : 'dxc-v-axis',
stripClass = isHorizontal ? 'dxc-h-strips' : 'dxc-v-strips',
constantLineClass = isHorizontal ? 'dxc-h-constant-lines' : 'dxc-v-constant-lines';
externalOptions = externalOptions || {};
var debug = DX.utils.debug;
debug.assertParam(this.translator, 'translator was not set before Draw call');
if (that._axisGroup) {
that._axisGroup.detach();
that._axisStripGroup.detach();
that._axisLableGroup.detach();
that._axisConstantLineGroup.detach();
that._axisTitleGroup ? that._axisTitleGroup.clear() : !adjustAxis && (that._axisTitleGroup = that.renderer.createGroup({'class': 'dxc-title'}).append(that._axisGroup));
that._axisGridGroup.clear();
that._axisElementsGroup ? that._axisElementsGroup.clear() : !adjustAxis && (that._axisElementsGroup = that.renderer.createGroup({'class': 'dxc-elements'}).append(that._axisGroup));
that._axisLineGroup.clear();
that._axisStripGroup.clear();
that._axisConstantLineGroup.clear();
that._axisLableGroup.clear()
}
else {
that._axisGroup = that.renderer.createGroup({
'class': cssClass,
clipId: that.clipRectID
});
that._axisStripGroup = that.renderer.createGroup({'class': stripClass});
that._axisGridGroup = that.renderer.createGroup({'class': 'dxc-grid'}).append(that._axisGroup);
that._axisElementsGroup = that.renderer.createGroup({'class': 'dxc-elements'}).append(that._axisGroup);
that._axisLineGroup = that.renderer.createGroup({'class': 'dxc-line'}).append(that._axisGroup);
that._axisTitleGroup = that.renderer.createGroup({'class': 'dxc-title'}).append(that._axisGroup);
that._axisConstantLineGroup = that.renderer.createGroup({'class': constantLineClass});
that._axisLableGroup = that.renderer.createGroup({'class': 'dxc-axis-labels'})
}
that._initAxisPositions();
if (!that._virtual) {
that._drawAxis();
that._drawTicks();
that._drawLabels();
that._drawTitle()
}
if (options.strips)
that._drawStrip();
if (options.constantLines)
that._drawConstantLine();
that._drawGrid(externalOptions.borderOptions);
that._axisStripGroup.append(that.stripsGroup);
that._axisConstantLineGroup.append(that.constantLinesGroup);
that._axisGroup.append(that.axesContainerGroup);
that._axisLableGroup.append(that.labelAxesGroup);
that._adjustConstantLineLabels();
that._adjustLabels();
that._adjustStripLabels();
that._adjustTitle();
that._setBoundingRect()
},
_setBoundingRect: function() {
var that = this,
options = that.options,
axisBox = that._axisElementsGroup ? that._axisElementsGroup.getBBox() : {
x: 0,
y: 0,
width: 0,
height: 0,
isEmpty: true
},
lineBox = that._axisLineGroup.getBBox(),
placeholderSize = options.placeholderSize,
start,
isHorizontal = options.isHorizontal,
coord = isHorizontal && 'y' || 'x',
side = isHorizontal && 'height' || 'width',
axisTitleBox = that.title && that._axisTitleGroup ? that._axisTitleGroup.getBBox() : axisBox;
if (axisBox.isEmpty && axisTitleBox.isEmpty && !placeholderSize) {
that.boundingRect = axisBox;
return
}
start = lineBox[coord] || that.axisPosition;
if (options.position === (isHorizontal && BOTTOM || RIGHT)) {
axisBox[side] = placeholderSize || axisTitleBox[coord] + axisTitleBox[side] - start;
axisBox[coord] = start
}
else {
axisBox[side] = placeholderSize || lineBox[side] + start - axisTitleBox[coord];
axisBox[coord] = axisTitleBox.isEmpty ? start : axisTitleBox[coord]
}
that.boundingRect = axisBox
},
getBoundingRect: function() {
return this._axisElementsGroup ? this.boundingRect : {
x: 0,
y: 0,
width: 0,
height: 0
}
},
shift: function(x, y) {
var settings = {};
if (x)
settings.translateX = x;
if (y)
settings.translateY = y;
this._axisGroup.applySettings(settings)
},
applyClipRect: function(clipId) {
this._axisStripGroup.applySettings({clipId: clipId})
},
validate: function(isArgumentAxis, incidentOccured) {
var that = this,
options = that.options,
range = options.range,
parseUtils = new core.ParseUtils,
dataType = isArgumentAxis ? options.argumentType : options.valueType,
parser = dataType ? parseUtils.getParser(dataType, 'axis') : function(unit) {
return unit
};
that.parser = parser;
that.incidentOccured = incidentOccured;
options.dataType = dataType;
if (options.min)
options.min = that.validateUnit(options.min, "E2106");
if (options.max)
options.max = that.validateUnit(options.max, "E2106");
if (range.min)
range.min = that.validateUnit(range.min);
if (range.max)
range.max = that.validateUnit(range.max)
},
validateUnit: function(unit, idError, parameters) {
var that = this,
dataType = that.options.dataType;
unit = that.parser(unit);
if (unit === undefined && idError)
that.incidentOccured(idError, [parameters]);
return unit
},
adjustZoomValues: function(min, max) {
var that = this,
range = that.options.range;
min = that.validateUnit(min);
max = that.validateUnit(max);
if (range && isDefinedUtils(range.min)) {
min = isDefinedUtils(min) ? range.min < min ? min : range.min : min;
max = isDefinedUtils(max) ? range.min < max ? max : range.min : max
}
if (range && isDefinedUtils(range.max)) {
max = isDefinedUtils(max) ? range.max > max ? max : range.max : max;
min = isDefinedUtils(min) ? range.max > min ? min : range.max : min
}
that.minRangeArg = min;
that.maxRangeArg = max;
return {
min: min,
max: max
}
},
getRangeData: function() {
var that = this,
options = that.options,
optionsRange = options.range,
range = {},
min,
max;
var addValueMarginToRange = function(prefix) {
if (options.valueMarginsEnabled) {
if (isDefinedUtils(options[prefix])) {
range[prefix] = options[prefix];
range[prefix + 'Priority'] = AXIS_VALUE_MARGIN_PRIORITY
}
}
else {
range[prefix] = 0;
range[prefix + 'Priority'] = AXIS_VALUE_MARGIN_PRIORITY
}
};
if (isDefinedUtils(optionsRange.min) && isDefinedUtils(optionsRange.max)) {
min = optionsRange.min < optionsRange.max ? optionsRange.min : optionsRange.max;
max = optionsRange.max > optionsRange.min ? optionsRange.max : optionsRange.min
}
else {
min = optionsRange.min;
max = optionsRange.max
}
range.min = min;
range.max = max;
addValueMarginToRange('minValueMargin');
addValueMarginToRange('maxValueMargin');
range.stick = !options.valueMarginsEnabled;
range.categories = optionsRange.categories;
range.dataType = options.dataType;
range.axisType = options.type;
if (range.axisType === 'logarithmic')
range.base = options.logarithmBase;
if (options.isHorizontal) {
range.minVisible = isDefinedUtils(that.minRangeArg) ? that.minRangeArg : optionsRange.min;
range.maxVisible = isDefinedUtils(that.maxRangeArg) ? that.maxRangeArg : optionsRange.max;
range.invert = options.inverted
}
else {
range.minVisible = optionsRange.min;
range.maxVisible = optionsRange.max;
range.invert = options.inverted || options.type === 'discrete' && options.oppositeDirectionYAxis
}
return range
}
})
})(jQuery, DevExpress);
/*! Module viz-charts, file baseChart.js */
(function($, DX, undefined) {
var ui = DX.ui,
charts = DX.viz.charts,
utils = DX.utils,
TRACKER_RENDERING_DELAY = 1200,
resizeRedrawOptions = {
animate: false,
isResize: true
},
ACTIONS_BY_PRIORITY = ['reinit', '_reinitDataSource', '_handleDataSourceChanged', 'force_render'],
core = DX.viz.core,
DEFAULT_ANIMATION_OPTIONS = {
asyncSeriesRendering: true,
asyncTrackersRendering: true,
trackerRenderingDelay: TRACKER_RENDERING_DELAY
};
charts.BaseChart = core.BaseWidget.inherit({
_setDefaultOptions: function() {
this.callBase();
this.option({
done: $.noop,
drawn: $.noop,
seriesClick: null,
pointClick: null,
legendClick: null,
argumentAxisClick: null,
seriesHover: null,
pointHover: null,
seriesSelected: null,
pointSelected: null,
seriesSelectionChanged: null,
pointSelectionChanged: null,
seriesHoverChanged: null,
pointHoverChanged: null
})
},
_createThemeManager: function() {
return charts.factory.createThemeManager(this.option())
},
_init: function() {
this.__TRACKER_RENDERING_DELAY = TRACKER_RENDERING_DELAY;
var that = this;
that.callBase();
that.themeManager = this._createThemeManager();
that._initRenderer();
that.canvasClipRect = that.renderer.createClipRect();
that._createHtmlStructure();
that._needHandleRenderComplete = true;
that.layoutManager = charts.factory.createChartLayoutManager(that.themeManager.getOptions("adaptiveLayout"));
that._reinit();
that._element().css({webkitUserSelect: 'none'}).on('contextmenu', function(event) {
that.eventType = 'contextmenu';
if (ui.events.isTouchEvent(event) || ui.events.isPointerEvent(event))
event.preventDefault()
}).on('MSHoldVisual', function(event) {
that.eventType = 'MSHoldVisual';
event.preventDefault()
})
},
_reinit: function() {
var that = this;
that.layoutManager.update(that);
that._createTracker();
that._reinitDataSource()
},
_createHtmlStructure: function() {
var that = this,
renderer = that.renderer;
that._panesBackgroundGroup = renderer.createGroup({'class': 'dxc-background'});
that._titleGroup = renderer.createGroup({'class': 'dxc-title'});
that._legendGroup = renderer.createGroup({
'class': 'dxc-legend',
clipId: that._getCanvasClipRectID()
});
that._stripsGroup = renderer.createGroup({'class': 'dxc-strips-group'});
that._constantLinesGroup = renderer.createGroup({'class': 'dxc-constant-lines-group'});
that._axesGroup = renderer.createGroup({'class': 'dxc-axes-group'});
that._panesBorderGroup = renderer.createGroup({'class': 'dxc-border'});
that._labelAxesGroup = renderer.createGroup({'class': 'dxc-strips-labels-group'});
that._seriesGroup = renderer.createGroup({'class': 'dxc-series-group'});
that._labelsGroup = renderer.createGroup({'class': 'dxc-labels-group'});
that._tooltipGroup = renderer.createGroup({'class': 'dxc-tooltip'});
that._trackerGroup = renderer.createGroup({
'class': 'dxc-trackers',
opacity: 0.0001,
stroke: "gray",
fill: "gray"
});
that._crosshairTrackerGroup = renderer.createGroup({
'class': 'dxc-crosshair-trackers',
stroke: 'none',
fill: 'grey'
}).append(that._trackerGroup);
that._seriesTrackerGroup = renderer.createGroup({'class': 'dxc-series-trackers'}).append(that._trackerGroup);
that._markerTrackerGroup = renderer.createGroup({
'class': 'dxc-markers-trackers',
stroke: 'none',
fill: 'grey'
}).append(that._trackerGroup);
that._crossHairCursorGroup = renderer.createGroup({'class': 'dxc-crosshair-cursor'})
},
_cleanHtmlStructure: function() {
var that = this;
that._panesBackgroundGroup && that._panesBackgroundGroup.clear();
that._titleGroup && that._titleGroup.clear();
that._legendGroup && (that._legendGroup.detach(), that._legendGroup.clear());
that._stripsGroup && (that._stripsGroup.detach(), that._stripsGroup.clear());
that._constantLinesGroup && (that._constantLinesGroup.detach(), that._constantLinesGroup.clear());
that._axesGroup && (that._axesGroup.detach(), that._axesGroup.clear());
that._labelAxesGroup && (that._labelAxesGroup.detach(), that._labelAxesGroup.clear());
that._seriesGroup && (that._seriesGroup.detach(), that._seriesGroup.clear());
that._labelsGroup && (that._labelsGroup.detach(), that._labelsGroup.clear());
that._trackerGroup && (that._trackerGroup.detach(), that._seriesTrackerGroup.clear(), that._markerTrackerGroup.clear(), that._crosshairTrackerGroup.clear());
that._panesBorderGroup && that._panesBorderGroup.clear();
that._tooltipGroup && that._tooltipGroup.clear();
that._crossHairCursorGroup && (that._crossHairCursorGroup.clear(), that._crossHairCursorGroup.detach())
},
_disposeObjectsInArray: function(propName, fieldNames) {
$.each(this[propName] || [], function(_, item) {
if (fieldNames && item)
$.each(fieldNames, function(_, field) {
item[field] && item[field].dispose()
});
else
item && item.dispose()
});
this[propName] = null
},
_dispose: function() {
var that = this,
disposeObject = function(propName) {
that[propName] && that[propName].dispose(),
that[propName] = null
},
detachGroup = function(groupName) {
that[groupName] && that[groupName].detach()
},
disposeObjectsInArray = this._disposeObjectsInArray;
clearTimeout(that.delayedRedraw);
that.callBase();
disposeObjectsInArray.call(that, "businessRanges", ["arg", "val"]);
that.translators = null;
disposeObjectsInArray.call(that, "series");
disposeObject("layoutManager");
disposeObject("themeManager");
disposeObject("renderer");
disposeObject("tracker");
disposeObject("tooltip");
disposeObject("chartTitle");
that.paneAxis = null;
that._userOptions = null;
that.dirtyCanvas = null;
that.canvas = null;
detachGroup("_legendGroup");
detachGroup("_stripsGroup");
detachGroup("_constantLinesGroup");
detachGroup("_axesGroup");
detachGroup("_labelAxesGroup");
detachGroup("_seriesGroup");
detachGroup("_labelsGroup");
detachGroup("_trackerGroup");
detachGroup("_crossHairCursorGroup");
disposeObject("canvasClipRect");
disposeObject("_panesBackgroundGroup");
disposeObject("_titleGroup");
disposeObject("_legendGroup");
disposeObject("_stripsGroup");
disposeObject("_constantLinesGroup");
disposeObject("_axesGroup");
disposeObject("_labelAxesGroup");
disposeObject("_panesBorderGroup");
disposeObject("_seriesGroup");
disposeObject("_labelsGroup");
disposeObject("_tooltipGroup");
disposeObject("_crossHairCursorGroup");
disposeObject("_seriesTrackerGroup");
disposeObject("_markerTrackerGroup");
disposeObject("_crosshairTrackerGroup");
disposeObject("_trackerGroup");
that._disposeLoadIndicator()
},
_clean: function _clean(hideLoadIndicator) {
this.renderer && this.renderer.stopAllAnimations();
hideLoadIndicator && this.hideLoadingIndicator();
this._cleanHtmlStructure();
this.callBase();
this._saveDirtyCanvas()
},
_getAnimationOptions: function() {
return $.extend({}, DEFAULT_ANIMATION_OPTIONS, this.themeManager.getOptions("animation"))
},
_initRenderer: function _initRenderer() {
if (this.renderer)
return;
this.renderer = core.CoreFactory.createRenderer({
animation: this._getAnimationOptions(),
cssClass: 'dxc dxc-chart',
pathModified: this.option('pathModified'),
rtl: this.themeManager.getOptions('rtlEnabled')
})
},
_initSeries: function() {
this.series = this.series || this._populateSeries()
},
_reinitDataSource: function() {
this._refreshDataSource()
},
_saveDirtyCanvas: function() {
this.dirtyCanvas = $.extend({}, this.canvas)
},
_resize: function() {
this._render(resizeRedrawOptions)
},
_calculateCanvas: function() {
var canvas = this.themeManager.getOptions('size'),
result = {},
container = this._element();
if (!utils.isDefined(canvas.width))
result.width = container.width() || 400;
else
result.width = canvas.width < 0 ? 0 : canvas.width;
if (!utils.isDefined(canvas.height))
result.height = container.height() || 400;
else
result.height = canvas.height < 0 ? 0 : canvas.height;
return $.extend({}, result, this.themeManager.getOptions('margin'))
},
_createTracker: function() {
var that = this,
tooltipOptions = that.themeManager.getOptions('tooltip') || {};
if (that.tracker)
that.tracker.dispose();
that.tracker = charts.factory.createTracker({
series: that.series,
valueAxis: that._valueAxes,
argumentAxis: that._argumentAxes,
seriesSelectionMode: that.themeManager.getOptions('seriesSelectionMode'),
pointSelectionMode: that.themeManager.getOptions('pointSelectionMode'),
tooltipShown: that.option('tooltipShown'),
tooltipHidden: that.option('tooltipHidden'),
markerTrackerGroup: that._markerTrackerGroup,
crossHairOptions: that._crossHairOptions,
seriesTrackerGroup: that._seriesTrackerGroup,
seriesGroup: that._seriesGroup,
tooltipEnabled: tooltipOptions.enabled,
renderer: that.renderer,
events: {
seriesClick: that.option('seriesClick'),
pointClick: that.option('pointClick'),
argumentAxisClick: that.option('argumentAxisClick'),
seriesHover: that.option('seriesHover'),
seriesSelected: that.option('seriesSelected'),
pointHover: that.option('pointHover'),
pointSelected: that.option('pointSelected'),
legendClick: that.option('legendClick'),
seriesSelectionChanged: that.option('seriesSelectionChanged'),
pointSelectionChanged: that.option('pointSelectionChanged'),
seriesHoverChanged: that.option('seriesHoverChanged'),
pointHoverChanged: that.option('pointHoverChanged')
}
})
},
_updateTracker: function() {
var that = this;
if (!that.tracker)
that._createTracker();
else
that.tracker._reinit({
series: that.series,
valueAxis: that._valueAxes,
argumentAxis: that._argumentAxes,
legendGroup: that.legend.getTrackerGroup(),
legendCallback: $.proxy(that.legend.getActionCallback, that.legend)
})
},
_render: function(drawOptions) {
this._optionsInitializing = false;
var that = this,
renderer = that.renderer,
updatedCanvas = that.canvas,
container = this._element(),
currentDirtyCanvas = that._calculateCanvas(),
oldDirtyCanvas = that.dirtyCanvas;
drawOptions = drawOptions || {recreateCanvas: true};
drawOptions.recreateCanvas = drawOptions.recreateCanvas || !renderer.isInitialized();
if (!drawOptions.force && oldDirtyCanvas && oldDirtyCanvas.width === currentDirtyCanvas.width && oldDirtyCanvas.height === currentDirtyCanvas.height && !that.hiddenContainer) {
that.stopRedraw = true;
return
}
clearTimeout(that.delayedRedraw);
if (drawOptions.recreateCanvas)
that.canvas = updatedCanvas = that._calculateCanvas();
if (updatedCanvas.width && updatedCanvas.height && container.is(':visible'))
that.hiddenContainer = false;
else {
that._incidentOccured('W2001', [that.NAME]);
that.hiddenContainer = true;
that.stopRedraw = true;
renderer.detachContainer();
return
}
if (drawOptions.recreateCanvas) {
renderer.recreateCanvas(that.canvas.width, that.canvas.height);
renderer.draw(that._element()[0]);
that._reappendLoadIndicator();
that._updateLoadIndicator(undefined, updatedCanvas.width, updatedCanvas.height);
that._updateCanvasClipRect()
}
that.renderer.stopAllAnimations(true);
that.layoutManager.update(that);
that._cleanGroups(drawOptions);
that._saveDirtyCanvas()
},
_cleanGroups: function(drawOptions) {
var that = this;
that._stripsGroup.detach();
that._constantLinesGroup.detach();
that._axesGroup.detach();
that._labelAxesGroup.detach();
that._labelsGroup.detach();
that._tooltipGroup.detach();
that._crossHairCursorGroup.detach();
if (!drawOptions || drawOptions.drawLegend) {
that._legendGroup.detach();
that._legendGroup.clear()
}
if (!drawOptions || drawOptions.drawTitle) {
that._titleGroup.detach();
that._titleGroup.clear()
}
that._stripsGroup.clear();
that._constantLinesGroup.clear();
that._axesGroup.clear();
that._labelAxesGroup.clear();
that._labelsGroup.clear();
that._tooltipGroup.clear();
that._crossHairCursorGroup.clear();
that._crosshairTrackerGroup.clear()
},
_drawTitle: function() {
var that = this,
options = that.themeManager.getOptions("title"),
width = that.canvas.width - that.canvas.left - that.canvas.right;
options._incidentOccured = that._incidentOccured;
if (that.chartTitle)
that.chartTitle.update(options, width);
else
that.chartTitle = charts.factory.createTitle(that.renderer, options, width, that._titleGroup)
},
_createTooltip: function() {
var that = this,
tooltipOptions = $.extend(true, {
canvasWidth: that.canvas.width,
canvasHeight: that.canvas.height
}, that.themeManager.getOptions('tooltip') || {}),
tooltipCoords,
point = this.tracker.pointAtShownTooltip;
if (!$.isFunction(tooltipOptions.customizeText) && utils.isDefined(tooltipOptions.customizeText)) {
that._incidentOccured("E2103", ['customizeText']);
tooltipOptions.customizeText = undefined
}
if (that.tooltip)
that.tooltip.update(tooltipOptions);
else
that.tooltip = core.CoreFactory.createTooltip(tooltipOptions, that._tooltipGroup, that.renderer);
that.tracker.setTooltip(that.tooltip);
if (point) {
tooltipCoords = point.getTooltipCoords();
that.tooltip.move(~~tooltipCoords.x, ~~tooltipCoords.y, tooltipCoords.offset);
that.tooltip.show()
}
},
_prepareDrawOptions: function(drawOptions) {
var animationOptions = this._getAnimationOptions(),
options;
options = $.extend({}, {
force: false,
adjustAxes: true,
drawLegend: true,
drawTitle: true,
adjustSeriesLabels: true,
animate: animationOptions.enabled,
animationPointsLimit: animationOptions.maxPointCountSupported,
asyncSeriesRendering: animationOptions.asyncSeriesRendering,
asyncTrackersRendering: animationOptions.asyncTrackersRendering,
trackerRenderingDelay: animationOptions.trackerRenderingDelay
}, drawOptions);
if (!utils.isDefined(options.recreateCanvas))
options.recreateCanvas = options.adjustAxes && options.drawLegend && options.drawTitle;
return options
},
_processRefreshData: function(newRefreshAction) {
var currentRefreshActionPosition = $.inArray(this._currentRefreshData, ACTIONS_BY_PRIORITY),
newRefreshActionPosition = $.inArray(newRefreshAction, ACTIONS_BY_PRIORITY);
if (!this._currentRefreshData || currentRefreshActionPosition >= 0 && newRefreshActionPosition < currentRefreshActionPosition)
this._currentRefreshData = newRefreshAction
},
_disposeSeries: function() {
var that = this;
that.tracker._clean();
$.each(that.series || [], function(_, series) {
series.dispose()
});
that.series = null;
$.each(that.seriesFamilies || [], function(_, family) {
family.dispose()
});
that.seriesFamilies = null
},
_optionChanged: function(name) {
var that = this,
themeManager = this.themeManager;
themeManager.resetOptions(name);
themeManager.update(that._options);
if (name === 'animation') {
that.renderer.updateAnimationOptions(this._getAnimationOptions());
return
}
clearTimeout(that.delayedRedraw);
switch (name) {
case'dataSource':
that._needHandleRenderComplete = true;
that._processRefreshData('_reinitDataSource');
break;
case'palette':
that.themeManager.updatePalette(this.option(name));
that._disposeSeries();
that._needHandleRenderComplete = true;
that._processRefreshData('_handleDataSourceChanged');
break;
case'series':
case'commonSeriesSettings':
case'containerBackgroundColor':
case'dataPrepareSettings':
that._disposeSeries();
that._needHandleRenderComplete = true;
that._processRefreshData('_handleDataSourceChanged');
break;
case'legend':
case'seriesTemplate':
that._processRefreshData('_handleDataSourceChanged');
break;
case'title':
that._processRefreshData('force_render');
break;
case'valueAxis':
case'argumentAxis':
case'commonAxisSettings':
that._needHandleRenderComplete = true;
that._processRefreshData('reinit');
that._disposeSeries();
that.paneAxis = {};
break;
case'panes':
case'defaultPane':
that._disposeSeries();
that.paneAxis = {};
that._needHandleRenderComplete = true;
that._processRefreshData('reinit');
break;
case'size':
that._processRefreshData('force_render');
break;
case'rotated':
case'equalBarWidth':
case'customizePoint':
case'customizeLabel':
that._disposeSeries();
that._needHandleRenderComplete = true;
that._processRefreshData('reinit');
break;
case'theme':
that._disposeSeries();
themeManager.setTheme(that.option(name));
that._processRefreshData('reinit');
break;
default:
that._processRefreshData('reinit')
}
that.callBase.apply(that, arguments)
},
_getLoadIndicatorOption: function() {
return this.themeManager.getOptions("loadingIndicator")
},
_refresh: function() {
var that = this;
this.renderer.stopAllAnimations(true);
if (that._currentRefreshData) {
switch (that._currentRefreshData) {
case'force_render':
that._render({force: true});
break;
case'reinit':
that._reinit(true);
break;
default:
that[that._currentRefreshData] && that[that._currentRefreshData]()
}
delete that._currentRefreshData
}
else
that._render({force: true})
},
_dataSourceOptions: function() {
return {
paginate: false,
_preferSync: true
}
},
_updateCanvasClipRect: function(canvas) {
var that = this,
width,
height;
canvas = canvas || that.canvas;
width = Math.max(canvas.width - canvas.left - canvas.right, 0);
height = Math.max(canvas.height - canvas.top - canvas.bottom, 0);
that.canvasClipRect.updateRectangle({
x: canvas.left,
y: canvas.top,
width: width,
height: height
});
that.canvasClipRect.append()
},
_getCanvasClipRectID: function() {
return this.canvasClipRect.id
},
_handleDataSourceChanged: function() {
clearTimeout(this.delayedRedraw);
this._dataSpecificInit(true)
},
_groupSeries: function() {
this._groupedSeries = [this.series]
},
_dataSpecificInit: function(needRedraw) {
this._initSeries();
this._repopulateSeries();
this._handleSeriesPopulated(needRedraw)
},
_processSingleSeries: function(){},
_repopulateSeries: function() {
var that = this,
parsedData,
data = that._dataSource && that._dataSource.items(),
dataValidatorOptions = that.themeManager.getOptions('dataPrepareSettings'),
seriesTemplate = that.themeManager.getOptions('seriesTemplate');
if (that._dataSource && seriesTemplate) {
that._templatedSeries = utils.processSeriesTemplate(seriesTemplate, that._dataSource.items());
that._populateSeries();
delete that._templatedSeries;
data = that.teamplateData || data
}
that._groupSeries();
that._dataValidator = charts.factory.createDataValidator(data, that._groupedSeries, that._incidentOccured, dataValidatorOptions);
parsedData = that._dataValidator.validate();
that.themeManager.resetPalette();
$.each(that.series, function(_, singleSeries) {
singleSeries.updateData(parsedData);
that._processSingleSeries(singleSeries)
})
},
_handleRenderComplete: function() {
var that = this,
userHandle = this.option('done'),
allSeriesInited = true;
if (that._needHandleRenderComplete) {
$.each(that.series, function(_, s) {
allSeriesInited = allSeriesInited && s.canRenderCompleteHandle()
});
if (allSeriesInited) {
that._needHandleRenderComplete = false;
$.isFunction(userHandle) && userHandle.call(that)
}
}
},
_renderTitleAndLegend: function(drawOptions, legendHasInsidePosition) {
var that = this,
titleOptions = that.themeManager.getOptions("title"),
drawTitle = titleOptions.text && drawOptions.drawTitle,
drawLegend = drawOptions.drawLegend && that.legend && !legendHasInsidePosition,
drawElements = [];
if (drawTitle) {
that._titleGroup.append();
that._drawTitle();
drawElements.push(that.chartTitle)
}
if (drawLegend) {
that._legendGroup.append();
drawElements.push(that.legend)
}
drawElements.length && that.layoutManager.drawElements(drawElements, that.canvas);
if (drawTitle)
that.layoutManager.correctSizeElement(that.chartTitle, that.canvas)
},
getAllSeries: function getAllSeries() {
return this.series.slice()
},
getSeriesByName: function getSeriesByName(name) {
var found = null;
$.each(this.series, function(i, singleSeries) {
if (singleSeries.name === name) {
found = singleSeries;
return false
}
});
return found
},
getSeriesByPos: function getSeriesByPos(pos) {
return this.series[pos]
},
getSelectedSeries: function getSelectedSeries() {
return null
},
clearSelection: function clearSelection() {
this.tracker.clearSelection()
},
hideTooltip: function() {
this.tracker._hideTooltip()
},
showLoadingIndicator: function() {
this._showLoadIndicator(this.themeManager.getOptions("loadingIndicator"), this.canvas || {})
},
render: function(renderOptions) {
this._render(renderOptions)
},
getSize: function() {
var canvas = this.canvas || {};
return {
width: canvas.width,
height: canvas.height
}
}
}).include(ui.DataHelperMixin)
})(jQuery, DevExpress);
/*! Module viz-charts, file chart.js */
(function($, DX, undefined) {
var core = DX.viz.core,
charts = DX.viz.charts,
utils = DX.utils,
MAX_ADJUSTMENT_ATTEMPTS = 5,
DEFAULT_PANE_NAME = 'default',
DEFAULT_AXIS_NAME = 'defaultAxisName',
DEFAULT_BUSINESS_RANGE_VALUE_MARGIN = 0.1,
ASYNC_SERIES_RENDERING_DELAY = 25,
_each = $.each;
function prepareAxis(axisOptions) {
return $.isArray(axisOptions) ? axisOptions.length === 0 ? [{}] : axisOptions : [axisOptions]
}
charts.Chart = charts.BaseChart.inherit({
_setDefaultOptions: function() {
this.callBase();
this.option({
defaultPane: DEFAULT_PANE_NAME,
panes: [{
name: DEFAULT_PANE_NAME,
border: {}
}]
})
},
_dispose: function() {
var that = this,
disposeObjectsInArray = this._disposeObjectsInArray;
that.callBase();
that.panes = null;
that.legend && (that.legend.dispose(), that.legend = null);
disposeObjectsInArray.call(that, "panesBackground");
disposeObjectsInArray.call(that, "panesClipRects");
disposeObjectsInArray.call(that, "financialPanesClipRects");
disposeObjectsInArray.call(that, "_argumentAxes");
disposeObjectsInArray.call(that, "_valueAxes");
disposeObjectsInArray.call(that, "seriesFamilies");
_each(that._paneTrackerGroups || [], function(_, groups) {
groups.paneSeriesGroup.dispose();
groups.paneMarkerGroup.dispose()
});
that._paneTrackerGroups = null
},
_init: function() {
this.__ASYNC_SERIES_RENDERING_DELAY = ASYNC_SERIES_RENDERING_DELAY;
this.paneAxis = {};
this._crossHairOptions = {};
this.callBase()
},
_reinit: function(needRedraw) {
var that = this;
that.translators = {};
that.panes = that._createPanes();
that._populateAxes();
that.callBase();
delete that._seriesInitializing;
if (!that.series)
that._dataSpecificInit();
else
that._correctValueAxes();
that._endLoading(function() {
needRedraw && that._render({force: true})
})
},
_correctBusinessRange: function(range, tickInterval, setTicksAtUnitBeginning) {
var min = 'min',
max = 'max';
if (!tickInterval || !utils.isDefined(range[min]) || !utils.isDefined(range[max]))
return false;
var tickIntervalRange = {},
originInterval = tickInterval;
tickInterval = $.isNumeric(tickInterval) ? tickInterval : utils.convertDateTickIntervalToMilliseconds(tickInterval);
if (tickInterval >= Math.abs(range[max] - range[min])) {
if (utils.isDate(range[min])) {
if (!$.isNumeric(originInterval)) {
tickIntervalRange[min] = utils.addInterval(range[min], originInterval, true);
tickIntervalRange[max] = utils.addInterval(range[max], originInterval, false)
}
else {
tickIntervalRange[min] = new Date(range[min].valueOf() - tickInterval);
tickIntervalRange[max] = new Date(range[max].valueOf() + tickInterval)
}
if (setTicksAtUnitBeginning) {
utils.correctDateWithUnitBeginning(tickIntervalRange[max], originInterval);
utils.correctDateWithUnitBeginning(tickIntervalRange[min], originInterval)
}
}
else {
tickIntervalRange[min] = range[min] - tickInterval;
tickIntervalRange[max] = range[max] + tickInterval
}
range.addRange(tickIntervalRange);
return true
}
return false
},
_seriesVisibilityChanged: function() {
this._processSeriesFamilies();
this._populateBusinessRange();
this.renderer.stopAllAnimations(true);
this._render({
force: true,
asyncSeriesRendering: false,
asyncTrackersRendering: false
})
},
_populateBusinessRange: function(visibleArea) {
var that = this,
businessRanges = [],
aggregationRange,
minBound,
maxBound,
i,
themeManager = that.themeManager,
rotated = themeManager.getOptions('rotated'),
singleSeriesRange,
valAxes = that._valueAxes,
valueAxes = {},
argAxes = that._argumentAxes,
useAggregation = themeManager.getOptions('useAggregation'),
argumentTickInterval,
setTicksAtUnitBeginning,
paneAxis = that.paneAxis,
groupedSeries = that._groupedSeries;
that._disposeObjectsInArray("businessRanges", ["arg", "val"]);
var argRange = new core.Range({
rotated: !!rotated,
minValueMargin: DEFAULT_BUSINESS_RANGE_VALUE_MARGIN,
maxValueMargin: DEFAULT_BUSINESS_RANGE_VALUE_MARGIN
});
_each(valAxes, function(_, axis) {
valueAxes[axis.name] = axis
});
_each(paneAxis, function(paneName, pane) {
_each(pane, function(axisName, _) {
var seriesForRange = [],
firstSeriesForRange,
options,
valueAxesForRange,
valRange = new core.Range({
isValueRange: true,
rotated: !!rotated,
pane: paneName,
axis: axisName,
minValueMargin: DEFAULT_BUSINESS_RANGE_VALUE_MARGIN,
maxValueMargin: DEFAULT_BUSINESS_RANGE_VALUE_MARGIN
}),
valueType,
calcInterval;
_each(groupedSeries, function(_, particularSeriesGroup) {
if (particularSeriesGroup[0].pane === paneName && particularSeriesGroup[0].axis === axisName)
seriesForRange = particularSeriesGroup
});
_each(valAxes, function(_, axis) {
if (axis.pane === paneName && axis.name === axisName) {
valueAxesForRange = axis;
return false
}
});
firstSeriesForRange = seriesForRange && seriesForRange.length ? seriesForRange[0] : {};
_each(argAxes, function(_, axis) {
var options = axis.options;
options.type = firstSeriesForRange.argumentAxisType || options.type;
options.argumentType = firstSeriesForRange.argumentType || options.argumentType;
axis.validate(true, that._incidentOccured);
argRange = argRange.addRange(axis.getRangeData());
argumentTickInterval = options.tickInterval;
setTicksAtUnitBeginning = options.setTicksAtUnitBeginning;
calcInterval = axis.calcInterval
});
options = valueAxesForRange.options;
options.type = firstSeriesForRange.valueAxisType || options.type;
options.valueType = firstSeriesForRange.valueType || options.valueType;
valueAxesForRange.validate(false, that._incidentOccured);
var axisRange = new core.Range(valueAxesForRange.getRangeData());
valueType = valueType || options.valueType === 'datetime' ? 'datetime' : undefined;
valRange = valRange.addRange(axisRange);
minBound = valRange.min;
maxBound = valRange.max;
for (i = 0; i < seriesForRange.length; i++) {
if (visibleArea) {
visibleArea.minVal = minBound;
visibleArea.maxVal = maxBound;
if (useAggregation && !visibleArea.adjustOnZoom) {
aggregationRange = seriesForRange[i]._originalBusinessRange;
visibleArea.minVal = utils.isDefined(visibleArea.minVal) ? visibleArea.minVal : aggregationRange.val.min;
visibleArea.maxVal = utils.isDefined(visibleArea.maxVal) ? visibleArea.maxVal : aggregationRange.val.max
}
}
singleSeriesRange = seriesForRange[i].getRangeData(visibleArea, calcInterval);
valRange = valRange.addRange(singleSeriesRange.val);
argRange = argRange.addRange(singleSeriesRange.arg)
}
if (!valRange.isDefined())
valRange.setStubData(valueType);
businessRanges.push({val: valRange})
})
});
if (!argRange.isDefined())
argRange.setStubData(argAxes[0].options.argumentType);
var bussinesRangeCorrectedWithTickInterval = that._correctBusinessRange(argRange, argumentTickInterval, setTicksAtUnitBeginning);
!bussinesRangeCorrectedWithTickInterval && argRange.applyValueMargins();
_each(businessRanges, function(_, item) {
var range = item.val,
vAxis = valueAxes[range.axis];
range.applyValueMargins();
if (vAxis && vAxis.options.showZero)
range.correctValueZeroLevel();
item.arg = argRange
});
that.businessRanges = businessRanges
},
_groupSeries: function() {
var that = this,
panes = that.panes,
valAxes = that._valueAxes,
paneList = $.map(panes, function(pane) {
return pane.name
}),
series = that.series,
paneAxis = that.paneAxis,
groupedSeries = that._groupedSeries = [];
var getFirstAxisNameForPane = function(axes, paneName) {
var result;
for (var i = 0; i < axes.length; i++)
if (axes[i].pane === paneName) {
result = axes[i].name;
break
}
if (!result)
result = valAxes[0].name;
return result
};
_each(series, function(i, particularSeries) {
particularSeries.axis = particularSeries.axis || getFirstAxisNameForPane(valAxes, particularSeries.pane);
if (particularSeries.axis) {
paneAxis[particularSeries.pane] = paneAxis[particularSeries.pane] || {};
paneAxis[particularSeries.pane][particularSeries.axis] = true
}
});
_each(valAxes, function(_, axis) {
if (axis.name && axis.pane && $.inArray(axis.pane, paneList) != -1) {
paneAxis[axis.pane] = paneAxis[axis.pane] || {};
paneAxis[axis.pane][axis.name] = true
}
});
that._correctValueAxes();
var hideGridsOnNonFirstValueAxisForPane = function(paneName) {
var axesForPane = [],
firstShownAxis;
_each(valAxes, function(_, axis) {
if (axis.pane === paneName)
axesForPane.push(axis)
});
if (axesForPane.length > 1 && that.themeManager.getOptions('synchronizeMultiAxes'))
_each(axesForPane, function(_, axis) {
var gridOpt = axis.options.grid;
if (firstShownAxis && gridOpt && gridOpt.visible)
gridOpt.visible = false;
else
firstShownAxis = firstShownAxis ? firstShownAxis : gridOpt && gridOpt.visible
})
};
_each(paneAxis, function(paneName, pane) {
hideGridsOnNonFirstValueAxisForPane(paneName);
_each(pane, function(axisName, _) {
var group = [];
_each(series, function(_, particularSeries) {
if (particularSeries.pane === paneName && particularSeries.axis === axisName)
group.push(particularSeries)
});
group.length && groupedSeries.push(group)
})
})
},
_cleanPanesClipRects: function(clipArrayName) {
var that = this,
clipArray = that[clipArrayName];
_each(clipArray || [], function(_, clipRect) {
clipRect && clipRect.remove()
});
that[clipArrayName] = []
},
_createPanes: function() {
var that = this,
panes = that.option('panes'),
panesNameCounter = 0,
bottomPaneName;
if (panes && utils.isArray(panes) && !panes.length || $.isEmptyObject(panes))
panes = that.initialOption("panes");
that._cleanPanesClipRects('panesClipRects');
that._cleanPanesClipRects('financialPanesClipRects');
that.defaultPane = that.option('defaultPane');
panes = $.isArray(panes) ? panes : panes ? [panes] : [];
_each(panes, function(_, pane) {
pane.name = !utils.isDefined(pane.name) ? DEFAULT_PANE_NAME + panesNameCounter++ : pane.name
});
if (!that._doesPaneExists(panes, that.defaultPane) && panes.length > 0) {
bottomPaneName = panes[panes.length - 1].name;
that._incidentOccured('W2101', [that.defaultPane, bottomPaneName]);
that.defaultPane = bottomPaneName
}
panes = that.themeManager.getOptions('rotated') ? panes.reverse() : panes;
return panes
},
_doesPaneExists: function(panes, paneName) {
var found = false;
_each(panes, function(_, pane) {
if (pane.name === paneName) {
found = true;
return false
}
});
return found
},
_populateSeries: function() {
var that = this,
themeManager = that.themeManager,
hasSeriesTemplate = !!themeManager.getOptions('seriesTemplate'),
series = hasSeriesTemplate ? that._templatedSeries : that.option('series'),
allSeriesOptions = $.isArray(series) ? series : series ? [series] : [],
argumentAxisOptions = that.option('argumentAxis'),
valueAxisOptions = that.option('valueAxis'),
data,
particularSeriesOptions,
particularSeries,
rotated = themeManager.getOptions('rotated'),
i,
paneList = $.map(that.panes, function(pane) {
return pane.name
}),
paneName,
paneIndex;
that.teamplateData = [];
_each(that._paneTrackerGroups || [], function(_, groups) {
groups.paneSeriesGroup.remove();
groups.paneMarkerGroup.remove()
});
that._paneTrackerGroups = [];
_each(that.panes, function(_, pane) {
var paneSeriesTrackerGroup = that.renderer.createGroup({'class': 'dxc-pane-tracker'}),
paneMarkerTrackerGroup = that.renderer.createGroup({'class': 'dxc-pane-tracker'});
that._paneTrackerGroups.push({
paneSeriesGroup: paneSeriesTrackerGroup,
paneMarkerGroup: paneMarkerTrackerGroup
})
});
that._disposeSeries();
that.series = [];
themeManager.resetPalette();
for (i = 0; i < allSeriesOptions.length; i++) {
particularSeriesOptions = $.extend(true, {}, allSeriesOptions[i]);
if (particularSeriesOptions.type && !utils.isString(particularSeriesOptions.type))
particularSeriesOptions.type = '';
data = particularSeriesOptions.data;
particularSeriesOptions.data = null;
particularSeriesOptions.rotated = rotated;
particularSeriesOptions.customizePoint = themeManager.getOptions("customizePoint");
particularSeriesOptions.customizeLabel = themeManager.getOptions("customizeLabel");
particularSeriesOptions.visibilityChanged = $.proxy(this._seriesVisibilityChanged, this);
particularSeriesOptions.resolveLabelsOverlapping = themeManager.getOptions("resolveLabelsOverlapping");
if (argumentAxisOptions) {
particularSeriesOptions.argumentCategories = argumentAxisOptions.categories;
particularSeriesOptions.argumentAxisType = argumentAxisOptions.type;
particularSeriesOptions.argumentType = argumentAxisOptions.argumentType
}
if (valueAxisOptions)
if (utils.isArray(valueAxisOptions))
_each(valueAxisOptions, function(iter, options) {
if (!particularSeriesOptions.axis && !iter || particularSeriesOptions.axis === options.name) {
particularSeriesOptions.valueCategories = options.categories;
particularSeriesOptions.valueAxisType = options.type;
particularSeriesOptions.valueType = options.valueType;
particularSeriesOptions.showZero = options.showZero
}
});
else {
particularSeriesOptions.valueCategories = valueAxisOptions.categories;
particularSeriesOptions.valueAxisType = valueAxisOptions.type;
particularSeriesOptions.valueType = valueAxisOptions.valueType;
particularSeriesOptions.showZero = valueAxisOptions.showZero
}
particularSeriesOptions.incidentOccured = that._incidentOccured;
if (!particularSeriesOptions.name)
particularSeriesOptions.name = 'Series ' + (i + 1).toString();
var seriesTheme = themeManager.getOptions("series", particularSeriesOptions);
seriesTheme.pane = seriesTheme.pane || that.defaultPane;
paneName = seriesTheme.pane;
paneIndex = that._getPaneIndex(paneName);
if ($.inArray(paneName, paneList) === -1)
continue;
seriesTheme.seriesGroup = that._seriesGroup;
seriesTheme.labelsGroup = that._labelsGroup;
seriesTheme.trackersGroup = that._paneTrackerGroups[paneIndex].paneSeriesGroup;
seriesTheme.markerTrackerGroup = that._paneTrackerGroups[paneIndex].paneMarkerGroup;
particularSeries = core.CoreFactory.createSeries(that.renderer, seriesTheme);
if (!particularSeries.isUpdated)
that._incidentOccured("E2101", [seriesTheme.type]);
else {
particularSeries.index = i;
that.series.push(particularSeries)
}
if (hasSeriesTemplate) {
_each(data, function(_, data) {
_each(particularSeries.getTeamplatedFields(), function(_, field) {
data[field.teamplateField] = data[field.originalField]
});
that.teamplateData.push(data)
});
particularSeries.updateTeamplateFieldNames()
}
}
return that.series
},
_createValueAxis: function(axisOptions, rotated, tickProvider) {
var that = this,
axis;
axisOptions = that.themeManager.getOptions("valueAxis", $.extend({
isHorizontal: rotated,
tickProvider: tickProvider,
incidentOccured: that._incidentOccured
}, axisOptions), rotated);
if (axisOptions.strips)
_each(axisOptions.strips, function(i, strips) {
axisOptions.strips[i] = $.extend(true, {}, axisOptions.stripStyle, axisOptions.strips[i])
});
if (axisOptions.constantLines)
_each(axisOptions.constantLines, function(i, line) {
axisOptions.constantLines[i] = $.extend(true, {}, axisOptions.constantLineStyle, line)
});
axis = charts.factory.createAxis(that.renderer, axisOptions);
axis.name = axisOptions.name;
axis.pane = axis.pane || axisOptions.pane;
axis.priority = axisOptions.priority;
return axis
},
_disposeAxes: function() {
var that = this;
_each(that._valueAxes || [], function(_, axis) {
axis.dispose()
});
_each(that._argumentAxes || [], function(_, axis) {
axis.dispose()
});
that._valueAxes = null;
that._argumentAxes = null
},
_populateAxes: function() {
var that = this,
valueAxes = [],
argumentAxes = [],
panes = that.panes,
themeManager = that.themeManager,
rotated = themeManager.getOptions('rotated'),
valueAxisOptions = that.option('valueAxis') || {},
argumentOption = that.option('argumentAxis') || {},
argumentAxesOptions = prepareAxis(argumentOption),
valueAxesOptions = prepareAxis(valueAxisOptions),
axis,
axisNames = [],
tickProvider = core.CoreFactory.getTickProvider(),
paneWithNonVirtualAxis;
that._disposeAxes();
var createArgumentAxis = function(axisOptions, virtual) {
axisOptions = that.themeManager.getOptions("argumentAxis", $.extend(true, {
isHorizontal: !rotated,
tickProvider: tickProvider,
pane: that.defaultPane,
incidentOccured: that._incidentOccured
}, axisOptions), rotated);
if (axisOptions.strips)
_each(axisOptions.strips, function(i, strips) {
axisOptions.strips[i] = $.extend(true, {}, axisOptions.stripStyle, axisOptions.strips[i])
});
if (axisOptions.constantLines)
_each(axisOptions.constantLines, function(i, line) {
axisOptions.constantLines[i] = $.extend(true, {}, axisOptions.constantLineStyle, line)
});
axis = charts.factory.createAxis(that.renderer, axisOptions);
axis._virtual = virtual;
argumentAxes.push(axis);
return axis
};
if (rotated)
paneWithNonVirtualAxis = argumentAxesOptions[0].position === 'right' ? panes[panes.length - 1].name : panes[0].name;
else
paneWithNonVirtualAxis = argumentAxesOptions[0].position === 'top' ? panes[0].name : panes[panes.length - 1].name;
_each(panes, function(_, pane) {
var paneName = pane.name,
virtual = paneName != paneWithNonVirtualAxis;
var axisOptions = $.extend(true, {}, argumentAxesOptions[0], {pane: paneName});
createArgumentAxis(axisOptions, virtual)
});
var valueAxesCounter = 0;
var getNextAxisName = function() {
return DEFAULT_AXIS_NAME + valueAxesCounter++
};
var unique = function(array) {
var values = {},
i,
len = array.length;
for (i = 0; i < len; i++)
values[array[i]] = true;
return $.map(values, function(_, key) {
return key
})
};
_each(valueAxesOptions, function(priority, axisOptions) {
var axisPanes = [],
name = axisOptions.name;
if (name && $.inArray(name, axisNames) != -1) {
that._incidentOccured("E2102");
return
}
name && axisNames.push(name);
if (axisOptions.pane)
axisPanes.push(axisOptions.pane);
if (axisOptions.panes && axisOptions.panes.length)
axisPanes = axisPanes.concat(axisOptions.panes.slice(0));
axisPanes = unique(axisPanes);
if (!axisPanes.length)
axisPanes.push(undefined);
_each(axisPanes, function(_, pane) {
valueAxes.push(that._createValueAxis($.extend(true, {}, axisOptions, {
name: name || getNextAxisName(),
pane: pane,
priority: priority
}), rotated, tickProvider))
})
});
that._valueAxes = valueAxes;
that._argumentAxes = argumentAxes
},
_correctValueAxes: function() {
var that = this,
rotated = that.themeManager.getOptions('rotated'),
valueAxisOptions = that.option('valueAxis') || {},
valueAxesOptions = $.isArray(valueAxisOptions) ? valueAxisOptions : [valueAxisOptions],
tickProvider = core.CoreFactory.getTickProvider(),
valueAxes = that._valueAxes || [],
defaultAxisName = valueAxes[0].name,
paneAxis = that.paneAxis || {},
panes = that.panes,
i,
neededAxis = {};
var getPaneForAxis = function(axisNameWithoutPane) {
var result;
_each(that.paneAxis, function(paneName, pane) {
_each(pane, function(axisName, _) {
if (axisNameWithoutPane == axisName) {
result = paneName;
return false
}
})
});
return result
};
var axesWithoutPanes = $.map(valueAxes, function(axis) {
if (axis.pane)
return null;
return axis
});
_each(axesWithoutPanes, function(_, axis) {
axis.pane = getPaneForAxis(axis.name);
if (!axis.pane) {
axis.pane = that.defaultPane;
paneAxis[axis.pane] = paneAxis[axis.pane] || {};
paneAxis[axis.pane][axis.name] = true
}
axis.options.pane = axis.pane
});
for (i = 0; i < panes.length; i++)
if (!paneAxis[panes[i].name]) {
paneAxis[panes[i].name] = {};
paneAxis[panes[i].name][defaultAxisName] = true
}
var findAxisOptions = function(axisName) {
var result,
axInd;
for (axInd = 0; axInd < valueAxesOptions.length; axInd++)
if (valueAxesOptions[axInd].name == axisName) {
result = valueAxesOptions[axInd];
result.priority = axInd;
break
}
if (!result)
for (axInd = 0; axInd < valueAxes.length; axInd++)
if (valueAxes[axInd].name == axisName) {
result = valueAxes[axInd].options;
result.priority = valueAxes[axInd].priority;
break
}
if (!result) {
that._incidentOccured("W2102", [axisName]);
result = {
name: axisName,
priority: valueAxes.length
}
}
return result
};
var findAxis = function(paneName, axisName) {
var axis;
for (i = 0; i < valueAxes.length; i++) {
axis = valueAxes[i];
if (axis.name === axisName && axis.pane === paneName)
return axis
}
};
_each(that.paneAxis, function(paneName, axisNames) {
_each(axisNames, function(axisName, _) {
neededAxis[axisName + '-' + paneName] = true;
if (!findAxis(paneName, axisName)) {
var axisOptions = findAxisOptions(axisName);
if (axisOptions)
valueAxes.push(that._createValueAxis($.extend(true, {}, axisOptions, {
pane: paneName,
name: axisName
}), rotated, tickProvider))
}
})
});
valueAxes = $.grep(valueAxes, function(elem) {
return !!neededAxis[elem.name + '-' + elem.pane]
});
valueAxes.sort(function(a, b) {
return a.priority - b.priority
});
that._valueAxes = valueAxes
},
_processSeriesFamilies: function() {
var that = this,
types = [],
families = [],
paneSeries,
themeManager = that.themeManager,
rotated = themeManager.getOptions('rotated');
if (that.seriesFamilies && that.seriesFamilies.length) {
_each(that.seriesFamilies, function(_, family) {
family.adjustSeriesValues()
});
return
}
_each(that.series, function(_, item) {
if ($.inArray(item.type, types) === -1)
types.push(item.type)
});
_each(that.panes, function(_, pane) {
paneSeries = [];
_each(that.series, function(_, oneSeries) {
if (oneSeries.pane === pane.name)
paneSeries.push(oneSeries)
});
_each(types, function(_, type) {
var family = core.CoreFactory.createSeriesFamily({
type: type,
pane: pane.name,
rotated: rotated,
equalBarWidth: themeManager.getOptions('equalBarWidth'),
minBubbleSize: themeManager.getOptions('minBubbleSize'),
maxBubbleSize: themeManager.getOptions('maxBubbleSize')
});
family.add(paneSeries);
family.adjustSeriesValues();
families.push(family)
})
});
that.seriesFamilies = families
},
_createLegend: function() {
var that = this,
legendData = [],
legendOptions = that.themeManager.getOptions('legend');
legendData = $.map(that.series, function(seriesItem) {
if (seriesItem.getOptions().showInLegend)
return {
text: seriesItem.name,
color: seriesItem.getColor(),
id: seriesItem.index,
states: seriesItem.getLegendStyles()
}
});
legendOptions.containerBackgroundColor = that.themeManager.getOptions("containerBackgroundColor");
legendOptions._incidentOccured = that._incidentOccured;
if (that.legend)
that.legend.update(legendData, legendOptions);
else
that.legend = core.CoreFactory.createLegend(legendData, legendOptions, that.renderer, that._legendGroup)
},
_createTranslator: function(range, canvas, options) {
return core.CoreFactory.createTranslator2D(range, canvas, options)
},
_createPanesBorderOptions: function() {
var commonBorderOptions = this.themeManager.getOptions('commonPaneSettings').border,
panesBorderOptions = {};
_each(this.panes, function(_, pane) {
var borderOptions = $.extend(true, {}, commonBorderOptions, pane.border);
panesBorderOptions[pane.name] = borderOptions
});
return panesBorderOptions
},
_render: function(drawOptions) {
var that = this,
themeManager = that.themeManager,
rotated = themeManager.getOptions('rotated'),
i,
layoutManager = that.layoutManager,
panesBorderOptions = that._createPanesBorderOptions(),
needHideLoadIndicator,
legendHasInsidePosition = that.legend && that.legend.getPosition() === "inside";
var drawSeries = function drawSeries() {
var panes = that.panes,
hideLayoutLabels = that.layoutManager.needMoreSpaceForPanesCanvas(that.panes, rotated) && !that.themeManager.getOptions("adaptiveLayout").keepLabels,
stackPoints = {};
_each(that.seriesFamilies || [], function(_, seriesFamily) {
var tr = that._getTranslator(seriesFamily.pane) || {},
translators = {};
translators[rotated ? 'x' : 'y'] = tr.val;
translators[rotated ? 'y' : 'x'] = tr.arg;
seriesFamily.updateSeriesValues(translators);
seriesFamily.adjustSeriesDimensions(translators)
});
that._createCrossHairCursor();
function applyPaneClipRect(seriesOptions) {
var paneIndex = that._getPaneIndex(seriesOptions.pane);
seriesOptions.setClippingParams(seriesOptions.isFinancialSeries() ? that.financialPanesClipRects[paneIndex].id : that.panesClipRects[paneIndex].id, that._getPaneBorderVisibility(paneIndex))
}
function preparePointsForSharedTooltip(singleSeries, stackPoints) {
if (!themeManager.getOptions('tooltip').shared)
return;
var points = singleSeries.getPoints(),
stackName = singleSeries.getStackName();
_each(points, function(index, point) {
var argument = point.argument;
if (!stackPoints[argument]) {
stackPoints[argument] = {};
stackPoints[argument][null] = []
}
if (stackName && !DX.utils.isArray(stackPoints[argument][stackName])) {
stackPoints[argument][stackName] = [];
_each(stackPoints[argument][null], function(_, point) {
if (!point.stackName)
stackPoints[argument][stackName].push(point)
})
}
if (stackName) {
stackPoints[argument][stackName].push(point);
stackPoints[argument][null].push(point)
}
else
_each(stackPoints[argument], function(_, stack) {
stack.push(point)
});
point.stackPoints = stackPoints[argument][stackName];
point.stackName = stackName
})
}
_each(that.series, function(_, particularSeries) {
preparePointsForSharedTooltip(particularSeries, stackPoints);
applyPaneClipRect(particularSeries);
particularSeries.setAdjustSeriesLabels(drawOptions.adjustSeriesLabels);
var tr = that._getTranslator(particularSeries.pane, particularSeries.axis),
translators = {};
translators[rotated ? 'x' : 'y'] = tr.val;
translators[rotated ? 'y' : 'x'] = tr.arg;
particularSeries.draw(translators, drawOptions.animate && particularSeries.getPoints().length <= drawOptions.animationPointsLimit && that.renderer.animationEnabled(), hideLayoutLabels, that.legend && that.legend.getActionCallback(particularSeries))
});
that._trackerGroup.append();
if (drawOptions.drawLegend && that.legend && legendHasInsidePosition) {
var newCanvas = $.extend({}, panes[0].canvas),
layoutManager = charts.factory.createChartLayoutManager();
newCanvas.right = panes[panes.length - 1].canvas.right;
newCanvas.bottom = panes[panes.length - 1].canvas.bottom;
that._legendGroup.append();
that._tooltipGroup.append();
layoutManager.drawElements([that.legend], newCanvas);
layoutManager.placeDrawnElements(newCanvas)
}
needHideLoadIndicator && that.hideLoadingIndicator();
that._drawn();
var drawChartTrackers = function drawChartTrackers() {
var i;
for (i = 0; i < that.series.length; i++)
that.series[i].drawTrackers();
if (that.legend) {
that.legend.drawTrackers();
legendHasInsidePosition && that._legendGroup.append();
legendHasInsidePosition && that._tooltipGroup.append()
}
that.tracker._prepare();
_each(that._paneTrackerGroups, function(index, paneGroups) {
paneGroups.paneSeriesGroup.append(that._seriesTrackerGroup);
paneGroups.paneMarkerGroup.append(that._markerTrackerGroup)
});
that._handleRenderComplete()
};
that._createTooltip();
if (drawOptions.asyncTrackersRendering)
that.delayedRedraw = setTimeout(drawChartTrackers, drawOptions.trackerRenderingDelay);
else
drawChartTrackers()
};
drawOptions = that._prepareDrawOptions(drawOptions);
that.callBase(drawOptions);
if (that.stopRedraw) {
that.stopRedraw = false;
return
}
that._createPanesBackground();
that._stripsGroup.append();
that._axesGroup.append();
that._constantLinesGroup.append();
that._labelAxesGroup.append();
that._createTranslators(drawOptions);
that._options.useAggregation && _each(that.series, function(_, series) {
series._originalBusinessRange = series._originalBusinessRange || series.getRangeData();
var tr = that._getTranslator(series.pane, series.axis),
translators = {};
translators[rotated ? 'x' : 'y'] = tr.val;
translators[rotated ? 'y' : 'x'] = tr.arg;
series.resamplePoints(translators, that._zoomMinArg, that._zoomMaxArg)
});
if (utils.isDefined(that._zoomMinArg) || utils.isDefined(that._zoomMaxArg))
that._populateBusinessRange({
adjustOnZoom: themeManager.getOptions('adjustOnZoom'),
minArg: that._zoomMinArg,
maxArg: that._zoomMaxArg
});
if (that._options.useAggregation || utils.isDefined(that._zoomMinArg) || utils.isDefined(that._zoomMaxArg))
that._updateTranslators();
that._renderTitleAndLegend(drawOptions, legendHasInsidePosition);
if (drawOptions && drawOptions.recreateCanvas)
layoutManager.updatePanesCanvases(that.panes, that.canvas, rotated);
that._drawAxes(panesBorderOptions, drawOptions);
if (layoutManager.needMoreSpaceForPanesCanvas(that.panes, rotated)) {
layoutManager.updateDrawnElements(that._argumentAxes, that._valueAxes, that.canvas, that.dirtyCanvas, that.panes, rotated);
if (that.chartTitle)
that.layoutManager.correctSizeElement(that.chartTitle, that.canvas);
that._updateCanvasClipRect(that.dirtyCanvas);
layoutManager.updatePanesCanvases(that.panes, that.canvas, rotated);
that._drawAxes(panesBorderOptions, drawOptions, true)
}
layoutManager.placeDrawnElements(that.canvas);
that._drawPanesBorders(panesBorderOptions);
that._createClipRectsForPanes();
for (i = 0; i < that._argumentAxes.length; i++)
that._argumentAxes[i].applyClipRect(that._getElementsClipRectID(that._argumentAxes[i].pane));
for (i = 0; i < that._valueAxes.length; i++)
that._valueAxes[i].applyClipRect(that._getElementsClipRectID(that._valueAxes[i].pane));
that._fillPanesBackground();
that._seriesGroup.append();
that._labelsGroup.append();
that._crossHairCursorGroup.append();
that._legendGroup.append();
that._tooltipGroup.append();
needHideLoadIndicator = that._loadIndicator && that._loadIndicator.isShown && that._dataSource && that._dataSource.isLoaded() && !drawOptions.isResize;
if (drawOptions.asyncSeriesRendering)
that.delayedRedraw = setTimeout(drawSeries, ASYNC_SERIES_RENDERING_DELAY);
else
drawSeries()
},
_createTranslators: function(drawOptions) {
var that = this,
rotated = that.themeManager.getOptions("rotated"),
translators;
if (!drawOptions.recreateCanvas)
return;
that.translators = translators = {};
that.layoutManager.updatePanesCanvases(that.panes, that.canvas, rotated);
_each(that.paneAxis, function(paneName, pane) {
translators[paneName] = translators[paneName] || {};
_each(pane, function(axisName, _) {
var translator = that._createTranslator(new core.Range(that._getBusinessRange(paneName, axisName).val), that._getCanvasForPane(paneName), rotated ? {direction: 'horizontal'} : {});
translator.pane = paneName;
translator.axis = axisName;
translators[paneName][axisName] = {val: translator}
})
});
_each(that._argumentAxes, function(_, axis) {
var translator = that._createTranslator(new core.Range(that._getBusinessRange(axis.pane).arg), that._getCanvasForPane(axis.pane), !rotated ? {direction: 'horizontal'} : {});
_each(translators[axis.pane], function(valAxis, paneAsixTran) {
paneAsixTran.arg = translator
})
})
},
_updateTranslators: function() {
var that = this;
_each(that.translators, function(pane, axisTrans) {
_each(axisTrans, function(axis, translator) {
translator.arg.updateBusinessRange(new core.Range(that._getBusinessRange(pane).arg));
delete translator.arg._originalBusinessRange;
translator.val.updateBusinessRange(new core.Range(that._getBusinessRange(pane, axis).val));
delete translator.val._originalBusinessRange
})
})
},
_reinitTranslators: function() {
var that = this;
_each(that._argumentAxes, function(_, axis) {
var translator = that._getTranslator(axis.pane);
if (translator) {
translator.arg.reinit();
axis.setRange(translator.arg.getBusinessRange());
axis.setTranslator(translator.arg, translator.val)
}
});
_each(that._valueAxes, function(_, axis) {
var translator = that._getTranslator(axis.pane, axis.name);
if (translator) {
translator.val.reinit();
axis.setRange(translator.val.getBusinessRange());
axis.setTranslator(translator.val, translator.arg)
}
})
},
_drawAxes: function(panesBorderOptions, drawOptions, adjustUnits) {
var that = this,
i = 0,
layoutManager = that.layoutManager,
rotated = that.themeManager.getOptions("rotated"),
translators = that.translators,
adjustmentCounter = 0,
synchronizeMultiAxes = that.themeManager.getOptions('synchronizeMultiAxes');
that._reinitTranslators();
do {
for (i = 0; i < that._argumentAxes.length; i++)
that._argumentAxes[i].resetTicks();
for (i = 0; i < that._valueAxes.length; i++)
that._valueAxes[i].resetTicks();
if (synchronizeMultiAxes)
charts.multiAxesSynchronizer.synchronize(that._valueAxes);
drawAxes(rotated ? that._valueAxes : that._argumentAxes);
layoutManager.requireAxesRedraw = false;
if (drawOptions.adjustAxes) {
layoutManager.applyHorizontalAxesLayout(rotated ? that._valueAxes : that._argumentAxes);
!layoutManager.stopDrawAxes && _each(translators, function(pane, axisTrans) {
_each(axisTrans, function(axis, translator) {
translator.arg.reinit();
translator.val.reinit()
})
})
}
drawAxes(rotated ? that._argumentAxes : that._valueAxes);
if (drawOptions.adjustAxes && !layoutManager.stopDrawAxes) {
layoutManager.applyVerticalAxesLayout(rotated ? that._argumentAxes : that._valueAxes);
!layoutManager.stopDrawAxes && _each(translators, function(pane, axisTrans) {
_each(axisTrans, function(axis, translator) {
translator.arg.reinit();
translator.val.reinit()
})
})
}
adjustmentCounter = adjustmentCounter + 1
} while (!layoutManager.stopDrawAxes && layoutManager.requireAxesRedraw && adjustmentCounter < MAX_ADJUSTMENT_ATTEMPTS);
that.__axisAdjustmentsCount = adjustmentCounter;
function drawAxes(axes) {
_each(axes, function(_, axis) {
axis.clipRectID = that._getCanvasClipRectID();
axis.stripsGroup = that._stripsGroup;
axis.labelAxesGroup = that._labelAxesGroup;
axis.constantLinesGroup = that._constantLinesGroup;
axis.axesContainerGroup = that._axesGroup;
axis.draw({borderOptions: panesBorderOptions[axis.pane]}, adjustUnits)
})
}
},
_createCrossHairCursor: function() {
var that = this,
renderer = that.renderer,
panes = that.panes,
commonCanvas,
canvas,
options = that.themeManager.getOptions('crosshair') || {},
hLine,
vLine,
attrHLine,
attrVLine,
i;
if (!options || !options.enabled)
return;
attrHLine = {
stroke: options.horizontalLine.color || options.color,
strokeWidth: options.horizontalLine.width || options.width,
dashStyle: options.horizontalLine.dashStyle || options.dashStyle,
visibility: 'hidden',
opacity: options.horizontalLine.opacity || options.opacity
};
attrVLine = {
stroke: options.verticalLine.color || options.color,
strokeWidth: options.verticalLine.width || options.width,
dashStyle: options.verticalLine.dashStyle || options.dashStyle,
visibility: 'hidden',
opacity: options.verticalLine.opacity || options.opacity
};
for (i = 0; i < panes.length; i++) {
canvas = panes[i].canvas;
if (!commonCanvas)
commonCanvas = $.extend({}, canvas);
else {
commonCanvas.right = canvas.right;
commonCanvas.bottom = canvas.bottom
}
renderer.createRect(canvas.left, canvas.top, canvas.width - canvas.right - canvas.left, canvas.height - canvas.bottom - canvas.top, 0).append(this._crosshairTrackerGroup)
}
if (options.horizontalLine && options.horizontalLine.visible)
hLine = renderer.createLine(commonCanvas.left, commonCanvas.top, commonCanvas.width - commonCanvas.right, commonCanvas.top, attrHLine).append(that._crossHairCursorGroup);
if (options.verticalLine && options.verticalLine.visible)
vLine = renderer.createLine(commonCanvas.left, commonCanvas.top, commonCanvas.left, commonCanvas.height - commonCanvas.bottom, attrVLine).append(that._crossHairCursorGroup);
that._crossHairOptions.horizontalLine = hLine;
that._crossHairOptions.verticalLine = vLine;
that._crossHairOptions.canvas = commonCanvas
},
_createPanesBackground: function() {
var that = this,
defaultBackgroundColor = that.themeManager.getOptions('commonPaneSettings').backgroundColor,
backgroundColor,
renderer = that.renderer,
rect,
i,
rects = [];
that._panesBackgroundGroup && that._panesBackgroundGroup.clear();
for (i = 0; i < that.panes.length; i++) {
backgroundColor = that.panes[i].backgroundColor || defaultBackgroundColor;
if (!backgroundColor || backgroundColor === 'none') {
rects.push(null);
continue
}
rect = renderer.createRect(0, 0, 0, 0, 0, {
fill: backgroundColor,
strokeWidth: 0
}).append(that._panesBackgroundGroup);
rects.push(rect)
}
that.panesBackground = rects;
that._panesBackgroundGroup.append()
},
_fillPanesBackground: function() {
var that = this,
bc;
_each(that.panes, function(i, pane) {
bc = pane.borderCoords;
if (that.panesBackground[i] != null)
that.panesBackground[i].applySettings({
x: bc.left,
y: bc.top,
width: bc.width,
height: bc.height
})
})
},
_calcPaneBorderCoords: function(pane, rotated) {
var canvas = pane.canvas,
bc = pane.borderCoords = pane.borderCoords || {};
bc.left = canvas.left;
bc.top = canvas.top;
bc.right = canvas.width - canvas.right;
bc.bottom = canvas.height - canvas.bottom;
bc.width = Math.max(bc.right - bc.left, 0);
bc.height = Math.max(bc.bottom - bc.top, 0)
},
_drawPanesBorders: function(panesBorderOptions) {
var that = this,
rotated = that.themeManager.getOptions('rotated');
that._panesBorderGroup && (that._panesBorderGroup.detach(), that._panesBorderGroup.clear());
_each(that.panes, function(i, pane) {
var bc,
borderOptions = panesBorderOptions[pane.name],
attr = {
fill: 'none',
stroke: borderOptions.color,
strokeOpacity: borderOptions.opacity,
strokeWidth: borderOptions.width,
dashStyle: borderOptions.dashStyle
};
that._calcPaneBorderCoords(pane, rotated);
if (!borderOptions.visible)
return;
bc = pane.borderCoords;
that.renderer.createSegmentRect(bc.left, bc.top, bc.width, bc.height, 0, borderOptions, attr).append(that._panesBorderGroup)
});
that._panesBorderGroup.append()
},
_createClipRect: function(clipArray, index, left, top, width, height) {
var that = this,
clipRect = clipArray[index];
if (!clipRect) {
clipRect = that.renderer.createClipRect(left, top, width, height);
clipArray[index] = clipRect
}
else
clipRect.updateRectangle({
x: left,
y: top,
width: width,
height: height
});
clipRect.append()
},
_createClipRectsForPanes: function() {
var that = this,
canvas = that.canvas;
_each(that.panes, function(i, pane) {
var hasFinancialSeries = false,
bc = pane.borderCoords,
left = bc.left,
top = bc.top,
width = bc.width,
height = bc.height;
that._createClipRect(that.panesClipRects, i, left, top, width, height);
_each(that.series, function(_, series) {
if (series.pane === pane.name && series.isFinancialSeries())
hasFinancialSeries = true
});
if (hasFinancialSeries) {
if (that.themeManager.getOptions('rotated')) {
top = 0;
height = canvas.height
}
else {
left = 0;
width = canvas.width
}
that._createClipRect(that.financialPanesClipRects, i, left, top, width, height)
}
else
that.financialPanesClipRects.push(null)
})
},
_getPaneIndex: function(paneName) {
var paneIndex;
_each(this.panes, function(index, pane) {
if (pane.name === paneName) {
paneIndex = index;
return false
}
});
return paneIndex
},
_getPaneBorderVisibility: function(paneIndex) {
var commonPaneBorderVisible = this.themeManager.getOptions('commonPaneSettings').border.visible,
pane = this.panes[paneIndex] || {},
paneBorder = pane.border || {};
return 'visible' in paneBorder ? paneBorder.visible : commonPaneBorderVisible
},
_getElementsClipRectID: function(paneName) {
return this.panesClipRects[this._getPaneIndex(paneName)].id
},
_getTranslator: function(paneName, axisName) {
var paneTrans = this.translators[paneName],
foundTranslator = null;
if (!paneTrans)
return foundTranslator;
foundTranslator = paneTrans[axisName];
if (!foundTranslator)
_each(paneTrans, function(axis, trans) {
foundTranslator = trans;
return false
});
return foundTranslator
},
_getCanvasForPane: function(paneName) {
var panes = this.panes,
panesNumber = panes.length,
i;
for (i = 0; i < panesNumber; i++)
if (panes[i].name === paneName)
return panes[i].canvas
},
_getBusinessRange: function(paneName, axisName) {
var ranges = this.businessRanges || [],
rangesNumber = ranges.length,
foundRange,
i;
for (i = 0; i < rangesNumber; i++)
if (ranges[i].val.pane === paneName && ranges[i].val.axis === axisName) {
foundRange = ranges[i];
break
}
if (!foundRange)
for (i = 0; i < rangesNumber; i++)
if (ranges[i].val.pane === paneName) {
foundRange = ranges[i];
break
}
return foundRange
},
_handleSeriesPopulated: function(needRedraw) {
var that = this;
that._processSeriesFamilies();
that._createLegend();
that._populateBusinessRange();
that._processValueAxisFormat();
that._updateTracker();
that._endLoading(function() {
needRedraw && that._render({force: true})
})
},
_processValueAxisFormat: function() {
var that = this,
valueAxes = that._valueAxes,
axesWithFullStackedFormat = [];
_each(that.series, function() {
if (this.isFullStackedSeries() && $.inArray(this.axis, axesWithFullStackedFormat) === -1)
axesWithFullStackedFormat.push(this.axis)
});
_each(valueAxes, function() {
if ($.inArray(this.name, axesWithFullStackedFormat) !== -1)
this.setPercentLabelFormat();
else
this.resetAutoLabelFormat()
})
},
zoomArgument: function(min, max) {
var that = this,
zoomArg = that._argumentAxes[0].adjustZoomValues(min, max);
that._zoomMinArg = zoomArg.min;
that._zoomMaxArg = zoomArg.max;
that._render({
force: true,
drawTitle: false,
drawLegend: false,
adjustAxes: false,
animate: false,
adjustSeriesLabels: false,
asyncSeriesRendering: false
})
}
})
})(jQuery, DevExpress);
/*! Module viz-charts, file pieChart.js */
(function($, DX, undefined) {
var core = DX.viz.core,
charts = DX.viz.charts,
utils = DX.utils;
charts.PieChart = charts.BaseChart.inherit({
_createThemeManager: function() {
return charts.factory.createThemeManager(this.option(), "pie")
},
_reinit: function(needRedraw) {
var that = this;
that.callBase();
if (!that.series)
that._dataSpecificInit();
that._endLoading(function() {
needRedraw && that._render({force: true})
})
},
_populateBusinessRange: function() {
var businessRanges = [],
series = this.series,
singleSeries = series[0],
range,
singleSeriesRange;
this._disposeObjectsInArray("businessRanges");
if (singleSeries) {
range = new core.Range({series: singleSeries});
singleSeriesRange = singleSeries.getRangeData();
range = range.addRange(singleSeriesRange.val);
if (!range.isDefined())
range.setStubData();
businessRanges.push(range)
}
this.businessRanges = businessRanges
},
_seriesVisibilytyChanged: function() {
this.series[0].arrangePoints();
this._populateBusinessRange();
this._refresh()
},
_createTranslator: function(range) {
return core.CoreFactory.createTranslator1D(range.min, range.max, 360, 0)
},
_populateSeries: function() {
var that = this,
renderer = that.renderer,
themeManager = that.themeManager,
hasSeriesTemplate = !!themeManager.getOptions("seriesTemplate"),
seriesOptions = hasSeriesTemplate ? that._templatedSeries : that.option("series"),
allSeriesOptions = $.isArray(seriesOptions) ? seriesOptions : seriesOptions ? [seriesOptions] : [],
data,
particularSeriesOptions,
particularSeries,
seriesTheme;
that._disposeSeries();
that.series = [];
themeManager.resetPalette();
if (allSeriesOptions.length) {
particularSeriesOptions = $.extend(true, {}, allSeriesOptions[0]);
if (particularSeriesOptions.type && !utils.isString(particularSeriesOptions.type))
particularSeriesOptions.type = "";
data = particularSeriesOptions.data;
particularSeriesOptions.data = null;
particularSeriesOptions.incidentOccured = that._incidentOccured;
seriesTheme = themeManager.getOptions("series", particularSeriesOptions, true);
seriesTheme.seriesGroup = that._seriesGroup;
seriesTheme.trackerGroup = that._trackerGroup;
seriesTheme.seriesLabelsGroup = that._labelsGroup;
seriesTheme.seriesTrackerGroup = that._seriesTrackerGroup;
seriesTheme.markerTrackerGroup = that._markerTrackerGroup;
seriesTheme.visibilityChanged = $.proxy(this._seriesVisibilytyChanged, this);
seriesTheme.customizePoint = themeManager.getOptions("customizePoint");
seriesTheme.customizeLabel = themeManager.getOptions("customizeLabel");
particularSeries = core.CoreFactory.createSeries(renderer, seriesTheme);
if (!particularSeries.isUpdated)
that._incidentOccured("E2101", [seriesTheme.type]);
else {
that._processSingleSeries(particularSeries);
that.series.push(particularSeries)
}
particularSeriesOptions.data = data
}
return that.series
},
_processSingleSeries: function(singleSeries) {
singleSeries.arrangePoints()
},
_handleSeriesPopulated: function(needRedraw) {
var that = this;
that._populateBusinessRange();
that._createLegend();
that._updateTracker();
that._endLoading(function() {
needRedraw && that._render({
force: true,
recreateCanvas: true
})
})
},
_createLegend: function() {
var that = this,
legendOptions = that.themeManager.getOptions("legend"),
data = $.map(that.series[0] ? that.series[0].getPoints() : [], function(item) {
return {
text: item.argument,
color: item.getColor(),
id: item.index,
states: item.getLegendStyles()
}
});
legendOptions._incidentOccured = that._incidentOccured;
that.legend = core.CoreFactory.createLegend(data, legendOptions, that.renderer, that._legendGroup)
},
_render: function(drawOptions) {
var that = this,
singleSeries = that.series && that.series[0],
layoutManager = that.layoutManager,
hideLayoutLabels;
drawOptions = that._prepareDrawOptions(drawOptions);
that.callBase(drawOptions);
if (that.stopRedraw) {
that.stopRedraw = false;
return
}
that._renderTitleAndLegend(drawOptions);
if (layoutManager.needMoreSpaceForPanesCanvas([that])) {
layoutManager.updateDrawnElements([], [], that.canvas, that.dirtyCanvas, [that]);
if (that.chartTitle)
that.layoutManager.correctSizeElement(that.chartTitle, that.canvas);
that._updateCanvasClipRect(that.dirtyCanvas)
}
layoutManager.placeDrawnElements(that.canvas);
if (singleSeries) {
hideLayoutLabels = layoutManager.needMoreSpaceForPanesCanvas([that]) && !that.themeManager.getOptions("adaptiveLayout").keepLabels;
layoutManager.applyPieChartSeriesLayout(that.canvas, singleSeries, true);
that._seriesGroup.append();
that._labelsGroup.append();
singleSeries.canvas = that.canvas;
singleSeries.resetLabelEllipsis();
singleSeries.draw(that._createTranslator(that.businessRanges[0], that.canvas), drawOptions.animate && that.renderer.animationEnabled(), hideLayoutLabels);
if (singleSeries.redraw) {
that.renderer.stopAllAnimations(true);
layoutManager.applyPieChartSeriesLayout(that.canvas, singleSeries, hideLayoutLabels);
singleSeries.draw(that._createTranslator(that.businessRanges[0], that.canvas), drawOptions.animate && that.renderer.animationEnabled(), hideLayoutLabels)
}
that._tooltipGroup.append();
that._trackerGroup.append();
that._createTooltip();
singleSeries.drawTrackers();
that.tracker._prepare("pieChart")
}
that._dataSource && that._dataSource.isLoaded() && !drawOptions.isResize && that.hideLoadingIndicator();
that._drawn();
that._handleRenderComplete()
},
getSeries: function getSeries() {
return this.series && this.series[0]
}
})
})(jQuery, DevExpress);
/*! Module viz-charts, file layoutManager.js */
(function($, DX, undefined) {
var isNumber = DX.utils.isNumber,
math = Math,
decreaseGaps = DevExpress.viz.core.utils.decreaseGaps,
CONNECTOR_MARGIN = 10,
round = math.round;
DX.viz.charts.LayoutManager = DX.Class.inherit(function() {
var ctor = function(options) {
this.verticalElements = [];
this.horizontalElements = [];
this._options = options
};
var update = function(chart) {
this.chart = chart;
setCanvasValues(chart && chart.canvas)
};
var dispose = function() {
this.chart = null
};
var setCanvasValues = function(canvas) {
if (canvas) {
canvas.originalTop = canvas.top;
canvas.originalBottom = canvas.bottom;
canvas.originalLeft = canvas.left;
canvas.originalRight = canvas.right
}
};
var placeElementAndCutCanvas = function(elements, canvas) {
$.each(elements, function(_, element) {
var shiftX,
shiftY,
options = element.getLayoutOptions(),
length = getLength(options.cutLayoutSide);
if (!options.width)
return;
switch (options.horizontalAlignment) {
case"left":
shiftX = canvas.left;
break;
case"center":
shiftX = (canvas.width - canvas.left - canvas.right - options.width) / 2 + canvas.left;
break;
case"right":
shiftX = canvas.width - canvas.right - options.width;
break
}
switch (options.verticalAlignment) {
case"top":
shiftY = canvas.top;
break;
case"bottom":
shiftY = canvas.height - canvas.bottom - options.height;
break
}
element.shift(round(shiftX), round(shiftY));
canvas[options.cutLayoutSide] += options[length];
setCanvasValues(canvas)
})
};
var drawElements = function(elements, canvas) {
var that = this,
verticalElements = that.verticalElements = [],
horizontalElements = that.horizontalElements = [];
$.each(elements, function(_, element) {
var freeHeight = canvas.height - canvas.top - canvas.bottom,
freeWidth = canvas.width - canvas.left - canvas.right,
options,
length,
arrayElements;
element.setSize({
height: freeHeight,
width: freeWidth
});
element.draw();
options = element.getLayoutOptions();
length = getLength(options.cutLayoutSide);
arrayElements = length === "width" ? horizontalElements : verticalElements;
arrayElements.push(element);
canvas[options.cutLayoutSide] += options[length];
setCanvasValues(canvas)
})
};
var getLength = function(side) {
var length = "height";
if (side === "left" || side === "right")
length = "width";
return length
};
var updatePanesCanvases = function(panes, canvas, rotated) {
var pane,
i,
paneSpaceHeight = canvas.height - canvas.top - canvas.bottom,
paneSpaceWidth = canvas.width - canvas.left - canvas.right,
weightSum = 0,
padding = panes.padding || 10;
for (i = 0; i < panes.length; i++) {
pane = panes[i];
pane.weight = pane.weight || 1;
weightSum = weightSum + pane.weight
}
rotated ? createPanes(panes, paneSpaceWidth, "left", "right") : createPanes(panes, paneSpaceHeight, "top", "bottom");
function createPanes(panes, paneSpace, startName, endName) {
var distributedSpace = 0,
oneWeight = (paneSpace - padding * (panes.length - 1)) / weightSum;
$.each(panes, function(_, pane) {
var calcLength = round(pane.weight * oneWeight);
pane.canvas = pane.canvas || {};
$.extend(pane.canvas, {
deltaLeft: 0,
deltaRight: 0,
deltaTop: 0,
deltaBottom: 0
}, canvas);
pane.canvas[startName] = canvas[startName] + distributedSpace;
pane.canvas[endName] = canvas[endName] + (paneSpace - calcLength - distributedSpace);
distributedSpace = distributedSpace + calcLength + padding;
setCanvasValues(pane.canvas)
})
}
};
var applyPieChartSeriesLayout = function(canvas, singleSeries, hideLayoutLabels) {
var paneSpaceHeight = canvas.height - canvas.top - canvas.bottom,
paneSpaceWidth = canvas.width - canvas.left - canvas.right,
paneCenterX = paneSpaceWidth / 2 + canvas.left,
paneCenterY = paneSpaceHeight / 2 + canvas.top,
accessibleRadius = Math.min(paneSpaceWidth, paneSpaceHeight) / 2,
minR = 0.7 * accessibleRadius,
innerRadius = getInnerRadius(singleSeries);
if (!hideLayoutLabels)
$.each(singleSeries.getPoints(), function(_, point) {
if (point._label.hasText() && point.isVisible()) {
var labelBBox = point._label._getOutsideGroupLabelPosition(),
nearestX = getNearestCoord(labelBBox.x, labelBBox.x + labelBBox.width, paneCenterX),
nearestY = getNearestCoord(labelBBox.y, labelBBox.y + labelBBox.height, paneCenterY),
minRadiusWithLabels = Math.max(getLengthFromCenter(nearestX, nearestY) - CONNECTOR_MARGIN, minR);
accessibleRadius = Math.min(accessibleRadius, minRadiusWithLabels)
}
point._label.setPosition(point._label.originalPosition)
});
else
$.each(singleSeries.getPoints(), function(_, point) {
if (singleSeries.getOptions().label.position === "inside")
return false;
point._label.originalPosition = point._label.getPosition();
point._label.setPosition('outside')
});
singleSeries.correctPosition({
centerX: math.floor(paneCenterX),
centerY: math.floor(paneCenterY),
radiusInner: math.floor(accessibleRadius * innerRadius),
radiusOuter: math.floor(accessibleRadius)
});
function getNearestCoord(firstCoord, secondCoord, pointCenterCoord) {
var nearestCoord;
if (pointCenterCoord < firstCoord)
nearestCoord = firstCoord;
else if (secondCoord < pointCenterCoord)
nearestCoord = secondCoord;
else
nearestCoord = pointCenterCoord;
return nearestCoord
}
function getLengthFromCenter(x, y) {
return Math.sqrt(Math.pow(x - paneCenterX, 2) + Math.pow(y - paneCenterY, 2))
}
function getInnerRadius(series) {
var innerRadius;
if (singleSeries.type === 'pie')
innerRadius = 0;
else {
innerRadius = singleSeries.innerRadius;
if (!isNumber(innerRadius))
innerRadius = 0.5;
else {
innerRadius = Number(innerRadius);
if (innerRadius < 0.2)
innerRadius = 0.2;
if (innerRadius > 0.8)
innerRadius = 0.8
}
}
return innerRadius
}
};
var isValidBox = function isValidBox(box) {
return !!(box.x || box.y || box.width || box.height)
};
var correctDeltaMarginValue = function(panes, marginSides) {
var axisPanePosition,
canvasCell,
canvas,
deltaSide,
requireAxesRedraw;
$.each(panes, function(_, pane) {
canvas = pane.canvas;
$.each(marginSides, function(_, side) {
deltaSide = 'delta' + side;
canvas[deltaSide] = Math.max(canvas[deltaSide] - (canvas[side.toLowerCase()] - canvas['original' + side]), 0);
if (canvas[deltaSide] > 0)
requireAxesRedraw = true
})
});
return requireAxesRedraw
};
var getPane = function getPane(name, panes) {
var findPane = panes[0];
$.each(panes, function(_, pane) {
if (name === pane.name)
findPane = pane
});
return findPane
};
var applyAxesLayout = function(axes, panes, rotated) {
var that = this,
canvas,
axisPanePosition,
axisPosition,
canvasCell,
box,
delta,
axis,
axisLength,
direction,
directionMultiplier,
someDirection = [],
pane,
i;
$.each(panes, function(_, pane) {
$.extend(pane.canvas, {
deltaLeft: 0,
deltaRight: 0,
deltaTop: 0,
deltaBottom: 0
})
});
for (i = 0; i < axes.length; i++) {
axis = axes[i];
axisPosition = axis.options.position || 'left';
axis.delta = {};
box = axis.getBoundingRect();
pane = getPane(axis.pane, panes);
canvas = pane.canvas;
if (!isValidBox(box))
continue;
direction = "delta" + axisPosition.slice(0, 1).toUpperCase() + axisPosition.slice(1);
switch (axisPosition) {
case"right":
directionMultiplier = 1;
canvas.deltaLeft += axis.padding ? axis.padding.left : 0;
break;
case"left":
directionMultiplier = -1;
canvas.deltaRight += axis.padding ? axis.padding.right : 0;
break;
case"top":
directionMultiplier = -1;
canvas.deltaBottom += axis.padding ? axis.padding.bottom : 0;
break;
case"bottom":
directionMultiplier = 1;
canvas.deltaTop += axis.padding ? axis.padding.top : 0;
break
}
switch (axisPosition) {
case"right":
case"left":
if (!box.isEmpty) {
delta = box.y + box.height - (canvas.height - canvas.originalBottom);
if (delta > 0) {
that.requireAxesRedraw = true;
canvas.deltaBottom += delta
}
delta = canvas.originalTop - box.y;
if (delta > 0) {
that.requireAxesRedraw = true;
canvas.deltaTop += delta
}
}
axisLength = box.width;
someDirection = ['Left', 'Right'];
break;
case"top":
case"bottom":
if (!box.isEmpty) {
delta = box.x + box.width - (canvas.width - canvas.originalRight);
if (delta > 0) {
that.requireAxesRedraw = true;
canvas.deltaRight += delta
}
delta = canvas.originalLeft - box.x;
if (delta > 0) {
that.requireAxesRedraw = true;
canvas.deltaLeft += delta
}
}
someDirection = ['Bottom', 'Top'];
axisLength = box.height;
break
}
if (!axis.delta[axisPosition] && canvas[direction] > 0)
canvas[direction] += axis.getMultipleAxesSpacing();
axis.delta[axisPosition] = axis.delta[axisPosition] || 0;
axis.delta[axisPosition] += canvas[direction] * directionMultiplier;
canvas[direction] += axisLength
}
that.requireAxesRedraw = correctDeltaMarginValue(panes, someDirection) || that.requireAxesRedraw;
this.stopDrawAxes = applyFoundExceedings(panes, rotated)
};
var applyVerticalAxesLayout = function(axes) {
var chart = this.chart;
this.applyAxesLayout(axes, chart.panes, chart.option('rotated'))
};
var applyHorizontalAxesLayout = function(axes) {
var chart = this.chart;
axes.reverse();
this.applyAxesLayout(axes, chart.panes, chart.option('rotated'));
axes.reverse()
};
var placeDrawnElements = function(canvas) {
var that = this,
horizontalElements = that.horizontalElements,
verticalElements = that.verticalElements;
correctElementsPosition(horizontalElements, 'width');
placeElementAndCutCanvas(horizontalElements, canvas);
correctElementsPosition(verticalElements, 'height');
placeElementAndCutCanvas(verticalElements, canvas);
function correctElementsPosition(elements, direction) {
$.each(elements, function(_, element) {
var options = element.getLayoutOptions(),
side = options.cutLayoutSide;
canvas[side] -= options[direction]
})
}
};
var needMoreSpaceForPanesCanvas = function(panes, rotated) {
var that = this,
needHorizontalSpace = 0,
needVerticalSpace = 0;
$.each(panes, function(_, pane) {
var paneCanvas = pane.canvas,
needPaneHorizonralSpace = that._options.width - (paneCanvas.width - paneCanvas.left - paneCanvas.right),
needPaneVerticalSpace = that._options.height - (paneCanvas.height - paneCanvas.top - paneCanvas.bottom);
if (rotated) {
needHorizontalSpace += needPaneHorizonralSpace > 0 ? needPaneHorizonralSpace : 0;
needVerticalSpace = Math.max(needPaneVerticalSpace > 0 ? needPaneVerticalSpace : 0, needVerticalSpace)
}
else {
needHorizontalSpace = Math.max(needPaneHorizonralSpace > 0 ? needPaneHorizonralSpace : 0, needHorizontalSpace);
needVerticalSpace += needPaneVerticalSpace > 0 ? needPaneVerticalSpace : 0
}
});
return needHorizontalSpace > 0 || needVerticalSpace > 0 ? {
width: needHorizontalSpace,
height: needVerticalSpace
} : false
};
var updateDrawnElements = function(argumentAxis, valueAxis, canvas, dirtyCanvas, panes, rotated) {
var that = this,
needRemoveSpace,
saveDirtyCanvas = $.extend({}, dirtyCanvas),
verticalAxes = rotated ? argumentAxis : valueAxis,
horizontalAxes = rotated ? valueAxis : argumentAxis;
needRemoveSpace = this.needMoreSpaceForPanesCanvas(panes, rotated);
if (!needRemoveSpace)
return;
needRemoveSpace.height = decreaseGaps(dirtyCanvas, ["top", "bottom"], needRemoveSpace.height);
needRemoveSpace.width = decreaseGaps(dirtyCanvas, ["left", "right"], needRemoveSpace.width);
canvas.top -= saveDirtyCanvas.top - dirtyCanvas.top;
canvas.bottom -= saveDirtyCanvas.bottom - dirtyCanvas.bottom;
canvas.left -= saveDirtyCanvas.left - dirtyCanvas.left;
canvas.right -= saveDirtyCanvas.right - dirtyCanvas.right;
updateElements(that.horizontalElements, "width", "height");
updateElements(that.verticalElements, "height", "width");
updateAxis(verticalAxes, "width");
updateAxis(horizontalAxes, "height");
function updateAxis(axes, side) {
if (axes && needRemoveSpace[side] > 0) {
$.each(axes, function(i, axis) {
var bbox = axis.getBoundingRect();
axis.updateSize();
needRemoveSpace[side] -= bbox[side] - axis.getBoundingRect()[side]
});
if (needRemoveSpace[side] > 0)
$.each(axes, function(_, axis) {
axis.updateSize(true)
})
}
}
function updateElements(elements, length, otherLength) {
$.each(elements, function(_, element) {
var options = element.getLayoutOptions(),
side = options.cutLayoutSide,
freeSpaceWidth = dirtyCanvas.width - dirtyCanvas.left - dirtyCanvas.right,
freeSpaceHeight = dirtyCanvas.height - dirtyCanvas.top - dirtyCanvas.bottom,
updateObject = {};
element.setSize({
width: freeSpaceWidth,
height: freeSpaceHeight
});
updateObject[otherLength] = 0;
updateObject[length] = needRemoveSpace[length];
element.changeSize(updateObject);
canvas[side] -= options[length] - element.getLayoutOptions()[length];
needRemoveSpace[length] -= options[length] - element.getLayoutOptions()[length]
})
}
};
var correctSizeElement = function(element, canvas) {
element.setSize({
width: canvas.width - canvas.right - canvas.left,
height: canvas.width - canvas.right - canvas.left
});
element.changeSize({
width: 0,
height: 0
})
};
var applyFoundExceedings = function applyFoundExceedings(panes, rotated) {
var col,
row,
stopDrawAxes,
maxLeft = 0,
maxRight = 0,
maxTop = 0,
maxBottom = 0,
maxColNumber = 0;
$.each(panes, function(_, pane) {
maxLeft = Math.max(maxLeft, pane.canvas.deltaLeft);
maxRight = Math.max(maxRight, pane.canvas.deltaRight);
maxTop = Math.max(maxTop, pane.canvas.deltaTop);
maxBottom = Math.max(maxBottom, pane.canvas.deltaBottom)
});
if (rotated)
$.each(panes, function(_, pane) {
pane.canvas.top += maxTop;
pane.canvas.bottom += maxBottom;
pane.canvas.right += pane.canvas.deltaRight;
pane.canvas.left += pane.canvas.deltaLeft
});
else
$.each(panes, function(_, pane) {
pane.canvas.top += pane.canvas.deltaTop;
pane.canvas.bottom += pane.canvas.deltaBottom;
pane.canvas.right += maxRight;
pane.canvas.left += maxLeft
});
$.each(panes, function(_, pane) {
if (pane.canvas.top + pane.canvas.bottom > pane.canvas.height)
stopDrawAxes = true;
if (pane.canvas.left + pane.canvas.right > pane.canvas.width)
stopDrawAxes = true
});
return stopDrawAxes
};
return {
ctor: ctor,
update: update,
drawElements: drawElements,
updatePanesCanvases: updatePanesCanvases,
applyVerticalAxesLayout: applyVerticalAxesLayout,
applyHorizontalAxesLayout: applyHorizontalAxesLayout,
applyAxesLayout: applyAxesLayout,
applyPieChartSeriesLayout: applyPieChartSeriesLayout,
dispose: dispose,
updateDrawnElements: updateDrawnElements,
placeDrawnElements: placeDrawnElements,
needMoreSpaceForPanesCanvas: needMoreSpaceForPanesCanvas,
correctSizeElement: correctSizeElement
}
}())
})(jQuery, DevExpress);
/*! Module viz-charts, file multiAxesSynchronizer.js */
(function($, DX, undefined) {
var Range = DX.viz.core.Range,
utils = DX.utils,
adjustValueUtils = utils.adjustValue,
applyPrecisionByMinDeltaUtils = utils.applyPrecisionByMinDelta,
isDefinedUtils = utils.isDefined,
math = Math,
mathFloor = math.floor,
mathMax = math.max,
_each = $.each,
MIN_RANGE_FOR_ADJUST_BOUNDS = 0.1;
var getValueAxesPerPanes = function(valueAxes) {
var result = {};
_each(valueAxes, function(_, axis) {
var pane = axis.pane;
if (!result[pane])
result[pane] = [];
result[pane].push(axis)
});
return result
};
var restoreOriginalBusinessRange = function(axis) {
var businessRange;
if (!axis.translator._originalBusinessRange)
axis.translator._originalBusinessRange = new Range(axis.translator.getBusinessRange());
else {
businessRange = new Range(axis.translator._originalBusinessRange);
axis.translator.updateBusinessRange(businessRange);
axis.setRange(businessRange)
}
};
var linearConvertor = {
transform: function(v, b) {
return utils.getLog(v, b)
},
addInterval: function(v, i) {
return v + i
},
getInterval: function(base, tickInterval) {
return tickInterval
},
adjustValue: mathFloor
};
var logConvertor = {
transform: function(v, b) {
return utils.raiseTo(v, b)
},
addInterval: function(v, i) {
return v * i
},
getInterval: function(base, tickInterval) {
return math.pow(base, tickInterval)
},
adjustValue: adjustValueUtils
};
var convertAxisInfo = function(axisInfo, convertor) {
if (!axisInfo.isLogarithmic)
return;
var base = axisInfo.logarithmicBase,
tickValues = axisInfo.tickValues,
tick,
ticks = [],
interval;
axisInfo.minValue = convertor.transform(axisInfo.minValue, base);
axisInfo.oldMinValue = convertor.transform(axisInfo.oldMinValue, base);
axisInfo.maxValue = convertor.transform(axisInfo.maxValue, base);
axisInfo.oldMaxValue = convertor.transform(axisInfo.oldMaxValue, base);
axisInfo.tickInterval = math.round(axisInfo.tickInterval);
if (axisInfo.tickInterval < 1)
axisInfo.tickInterval = 1;
interval = convertor.getInterval(base, axisInfo.tickInterval);
for (tick = convertor.adjustValue(convertor.transform(tickValues[0], base)); ticks.length < tickValues.length; tick = convertor.addInterval(tick, interval))
ticks.push(tick);
ticks.tickInterval = axisInfo.tickInterval;
axisInfo.tickValues = ticks
};
var populateAxesInfo = function(axes) {
return $.map(axes, function(axis) {
restoreOriginalBusinessRange(axis);
var tickValues = axis.getTickValues(),
options = axis.options,
minValue,
maxValue,
axisInfo = null,
businessRange,
tickInterval,
synchronizedValue;
if (tickValues && tickValues.length > 0 && utils.isNumber(tickValues[0]) && options.type !== 'discrete') {
tickInterval = tickValues.tickInterval;
businessRange = axis.translator.getBusinessRange();
minValue = businessRange.minVisible;
maxValue = businessRange.maxVisible;
synchronizedValue = options.synchronizedValue;
if (minValue === maxValue && isDefinedUtils(synchronizedValue)) {
minValue = tickValues[0] - 1;
maxValue = tickValues[0] + 1;
tickInterval = 1
}
axisInfo = {
axis: axis,
isLogarithmic: options.type === 'logarithmic',
logarithmicBase: businessRange.base,
tickValues: tickValues,
minValue: minValue,
oldMinValue: minValue,
maxValue: maxValue,
oldMaxValue: maxValue,
inverted: businessRange.invert,
tickInterval: tickInterval,
synchronizedValue: synchronizedValue
};
if (businessRange.stubData) {
axisInfo.stubData = true;
axisInfo.tickInterval = axisInfo.tickInterval || options.tickInterval;
axisInfo.isLogarithmic = false
}
convertAxisInfo(axisInfo, linearConvertor);
DX.utils.debug.assert(axisInfo.tickInterval !== undefined && axisInfo.tickInterval !== null, 'tickInterval was not provided')
}
return axisInfo
})
};
var updateTickValues = function(axesInfo) {
var maxTicksCount = 0;
_each(axesInfo, function(_, axisInfo) {
maxTicksCount = mathMax(maxTicksCount, axisInfo.tickValues.length)
});
_each(axesInfo, function(_, axisInfo) {
var ticksMultiplier,
ticksCount,
additionalStartTicksCount = 0,
synchronizedValue = axisInfo.synchronizedValue,
tickValues = axisInfo.tickValues,
tickInterval = axisInfo.tickInterval;
if (isDefinedUtils(synchronizedValue)) {
axisInfo.baseTickValue = axisInfo.invertedBaseTickValue = synchronizedValue;
axisInfo.tickValues = [axisInfo.baseTickValue]
}
else {
if (tickValues.length > 1 && tickInterval) {
ticksMultiplier = mathFloor((maxTicksCount + 1) / tickValues.length);
ticksCount = ticksMultiplier > 1 ? mathFloor((maxTicksCount + 1) / ticksMultiplier) : maxTicksCount;
additionalStartTicksCount = mathFloor((ticksCount - tickValues.length) / 2);
while (additionalStartTicksCount > 0 && tickValues[0] !== 0) {
tickValues.unshift(applyPrecisionByMinDeltaUtils(tickValues[0], tickInterval, tickValues[0] - tickInterval));
additionalStartTicksCount--
}
while (tickValues.length < ticksCount)
tickValues.push(applyPrecisionByMinDeltaUtils(tickValues[0], tickInterval, tickValues[tickValues.length - 1] + tickInterval));
axisInfo.tickInterval = tickInterval / ticksMultiplier
}
axisInfo.baseTickValue = tickValues[0];
axisInfo.invertedBaseTickValue = tickValues[tickValues.length - 1]
}
})
};
var getAxisRange = function(axisInfo) {
return axisInfo.maxValue - axisInfo.minValue || 1
};
var getMainAxisInfo = function(axesInfo) {
for (var i = 0; i < axesInfo.length; i++)
if (!axesInfo[i].stubData)
return axesInfo[i];
return null
};
var correctMinMaxValues = function(axesInfo) {
var mainAxisInfo = getMainAxisInfo(axesInfo),
mainAxisInfoTickInterval = mainAxisInfo.tickInterval;
_each(axesInfo, function(_, axisInfo) {
var scale,
move,
mainAxisBaseValueOffset,
valueFromAxisInfo;
if (axisInfo !== mainAxisInfo) {
if (mainAxisInfoTickInterval && axisInfo.tickInterval) {
if (axisInfo.stubData && isDefinedUtils(axisInfo.synchronizedValue)) {
axisInfo.oldMinValue = axisInfo.minValue = axisInfo.baseTickValue - (mainAxisInfo.baseTickValue - mainAxisInfo.minValue) / mainAxisInfoTickInterval * axisInfo.tickInterval;
axisInfo.oldMaxValue = axisInfo.maxValue = axisInfo.baseTickValue - (mainAxisInfo.baseTickValue - mainAxisInfo.maxValue) / mainAxisInfoTickInterval * axisInfo.tickInterval
}
scale = mainAxisInfoTickInterval / getAxisRange(mainAxisInfo) / axisInfo.tickInterval * getAxisRange(axisInfo);
axisInfo.maxValue = axisInfo.minValue + getAxisRange(axisInfo) / scale
}
if (mainAxisInfo.inverted && !axisInfo.inverted || !mainAxisInfo.inverted && axisInfo.inverted)
mainAxisBaseValueOffset = mainAxisInfo.maxValue - mainAxisInfo.invertedBaseTickValue;
else
mainAxisBaseValueOffset = mainAxisInfo.baseTickValue - mainAxisInfo.minValue;
valueFromAxisInfo = getAxisRange(axisInfo);
move = (mainAxisBaseValueOffset / getAxisRange(mainAxisInfo) - (axisInfo.baseTickValue - axisInfo.minValue) / valueFromAxisInfo) * valueFromAxisInfo;
axisInfo.minValue -= move;
axisInfo.maxValue -= move
}
})
};
var calculatePaddings = function(axesInfo) {
var minPadding,
maxPadding,
startPadding = 0,
endPadding = 0;
_each(axesInfo, function(_, axisInfo) {
var inverted = axisInfo.inverted;
minPadding = axisInfo.minValue > axisInfo.oldMinValue ? (axisInfo.minValue - axisInfo.oldMinValue) / getAxisRange(axisInfo) : 0;
maxPadding = axisInfo.maxValue < axisInfo.oldMaxValue ? (axisInfo.oldMaxValue - axisInfo.maxValue) / getAxisRange(axisInfo) : 0;
startPadding = mathMax(startPadding, inverted ? maxPadding : minPadding);
endPadding = mathMax(endPadding, inverted ? minPadding : maxPadding)
});
return {
start: startPadding,
end: endPadding
}
};
var correctMinMaxValuesByPaddings = function(axesInfo, paddings) {
_each(axesInfo, function(_, info) {
var range = getAxisRange(info),
inverted = info.inverted;
info.minValue -= paddings[inverted ? 'end' : 'start'] * range;
info.maxValue += paddings[inverted ? 'start' : 'end'] * range;
if (range > MIN_RANGE_FOR_ADJUST_BOUNDS) {
info.minValue = math.min(info.minValue, adjustValueUtils(info.minValue));
info.maxValue = mathMax(info.maxValue, adjustValueUtils(info.maxValue))
}
})
};
var updateTickValuesIfSyncronizedValueUsed = function(axesInfo) {
var hasSyncronizedValue = false;
_each(axesInfo, function(_, info) {
hasSyncronizedValue = hasSyncronizedValue || isDefinedUtils(info.synchronizedValue)
});
_each(axesInfo, function(_, info) {
var lastTickValue,
tickInterval = info.tickInterval,
tickValues = info.tickValues,
maxValue = info.maxValue,
minValue = info.minValue;
if (hasSyncronizedValue && tickInterval) {
while (tickValues[0] - tickInterval >= minValue)
tickValues.unshift(adjustValueUtils(tickValues[0] - tickInterval));
lastTickValue = tickValues[tickValues.length - 1];
while ((lastTickValue = lastTickValue + tickInterval) <= maxValue)
tickValues.push(utils.isExponential(lastTickValue) ? adjustValueUtils(lastTickValue) : utils.applyPrecisionByMinDelta(minValue, tickInterval, lastTickValue))
}
while (tickValues[0] < minValue)
tickValues.shift();
while (tickValues[tickValues.length - 1] > maxValue)
tickValues.pop()
})
};
var applyMinMaxValues = function(axesInfo) {
_each(axesInfo, function(_, info) {
var axis = info.axis,
range = axis.translator.getBusinessRange();
if (range.min === range.minVisible)
range.min = info.minValue;
if (range.max === range.maxVisible)
range.max = info.maxValue;
range.minVisible = info.minValue;
range.maxVisible = info.maxValue;
if (isDefinedUtils(info.stubData))
range.stubData = info.stubData;
if (range.min > range.minVisible)
range.min = range.minVisible;
if (range.max < range.maxVisible)
range.max = range.maxVisible;
axis.translator.updateBusinessRange(range);
axis.setRange(range);
axis.setTickValues(info.tickValues)
})
};
var correctAfterSynchronize = function(axesInfo) {
var invalidAxisInfo = [],
correctValue,
validAxisInfo;
_each(axesInfo, function(i, info) {
if (info.oldMaxValue - info.oldMinValue === 0)
invalidAxisInfo.push(info);
else if (!isDefinedUtils(correctValue) && !isDefinedUtils(info.synchronizedValue)) {
correctValue = math.abs((info.maxValue - info.minValue) / (info.tickValues[mathFloor(info.tickValues.length / 2)] || info.maxValue));
validAxisInfo = info
}
});
if (!isDefinedUtils(correctValue))
return;
_each(invalidAxisInfo, function(i, info) {
var firstTick = info.tickValues[0],
correctedTick = firstTick * correctValue,
tickValues = validAxisInfo.tickValues,
centralTick = tickValues[mathFloor(tickValues.length / 2)];
if (firstTick > 0) {
info.maxValue = correctedTick;
info.minValue = 0
}
else if (firstTick < 0) {
info.minValue = correctedTick;
info.maxValue = 0
}
else if (firstTick === 0) {
info.maxValue = validAxisInfo.maxValue - centralTick;
info.minValue = validAxisInfo.minValue - centralTick
}
})
};
DX.viz.charts.multiAxesSynchronizer = {synchronize: function(valueAxes) {
_each(getValueAxesPerPanes(valueAxes), function(_, axes) {
var axesInfo,
paddings;
if (axes.length > 1) {
axesInfo = populateAxesInfo(axes);
if (axesInfo.length === 0 || !getMainAxisInfo(axesInfo))
return;
updateTickValues(axesInfo);
correctMinMaxValues(axesInfo);
paddings = calculatePaddings(axesInfo);
correctMinMaxValuesByPaddings(axesInfo, paddings);
correctAfterSynchronize(axesInfo);
updateTickValuesIfSyncronizedValueUsed(axesInfo);
_each(axesInfo, function() {
convertAxisInfo(this, logConvertor)
});
applyMinMaxValues(axesInfo)
}
})
}}
})(jQuery, DevExpress);
/*! Module viz-charts, file tracker.js */
(function($, DX) {
var charts = DX.viz.charts,
eventsConsts = DX.viz.core.series.helpers.consts.events,
utils = DX.utils,
isFunction = utils.isFunction,
isDefined = utils.isDefined,
MULTIPLE_MODE = 'multiple',
SINGLE_MODE = 'single',
ALL_ARGUMENTS_POINTS_MODE = 'allargumentpoints',
ALL_SERIES_POINTS_MODE = 'allseriespoints',
msPointerEnabled = window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints || window.navigator.pointerEnabled && window.navigator.maxTouchPoints || null,
MOUSE_EVENT_LOCK_TIMEOUT = 1000,
CLICK_EVENT_LOCK_TIMEOUT = 600,
HOVER_START_DELAY = 100,
HOVER_HOLD_DELAY = 200,
TOOLTIP_HOLD_TIMEOUT = 400,
NONE_MODE = 'none';
var processMode = function(mode) {
return (mode + "").toLowerCase()
};
charts.Tracker = DX.Class.inherit({
ctor: function(options) {
this.__HOVER_HOLD_DELAY = HOVER_HOLD_DELAY;
this.__TOOLTIP_HOLD_TIMEOUT = TOOLTIP_HOLD_TIMEOUT;
this.__HOVER_START_DELAY = HOVER_START_DELAY;
var that = this,
events = options.events = options.events || {},
getEventHandler = function(func) {
return func && func.call ? function() {
var eventContext = this,
eventArgs = arguments;
setTimeout(function() {
func.apply(eventContext, eventArgs)
})
} : null
};
that._reinit(options);
that.pointSelectionMode = that._prepareMode(options.pointSelectionMode);
that.seriesSelectionMode = that._prepareMode(options.seriesSelectionMode);
that.hoverStartDelay = 0;
that.sensitivity = 7;
if (that.pointSelectionMode === MULTIPLE_MODE) {
that._releaseSelectedPoint = that._releaseSelectedPointMultiMode;
that.selectedPoint = []
}
else
that._releaseSelectedPoint = that._releaseSelectedPointSingleMode;
if (that.seriesSelectionMode === MULTIPLE_MODE) {
that._releaseSelectedSeries = that._releaseSelectedSeriesMultiMode;
that.selectedSeries = []
}
else
that._releaseSelectedSeries = that._releaseSelectedSeriesSingleMode;
that.tooltipEnabled = options.tooltipEnabled;
that.tooltipShown = options.tooltipShown;
that.tooltipHidden = options.tooltipHidden;
that.seriesClick = getEventHandler(events.seriesClick);
that.pointClick = getEventHandler(events.pointClick);
that.legendClick = getEventHandler(events.legendClick);
that.argumentAxisClick = getEventHandler(events.argumentAxisClick);
that.seriesHover = getEventHandler(events.seriesHover);
that.seriesSelected = getEventHandler(events.seriesSelected);
that.pointHover = getEventHandler(events.pointHover);
that.seriesSelectionChanged = getEventHandler(events.seriesSelectionChanged);
that.pointSelectionChanged = getEventHandler(events.pointSelectionChanged);
that.seriesHoverChanged = getEventHandler(events.seriesHoverChanged);
that.pointHoverChanged = getEventHandler(events.pointHoverChanged);
that.pointSelected = getEventHandler(events.pointSelected);
that.renderer = options.renderer;
that.seriesTrackerGroup = options.seriesTrackerGroup;
that.markerTrackerGroup = options.markerTrackerGroup;
that.seriesGroup = options.seriesGroup;
that.seriesGroup.on(eventsConsts.selectSeries, {tracker: that}, that._selectSeries);
that.seriesGroup.on(eventsConsts.deselectSeries, {tracker: that}, that._deselectSeries);
that.seriesGroup.on(eventsConsts.selectPoint, {tracker: that}, that._selectPoint);
that.seriesGroup.on(eventsConsts.deselectPoint, {tracker: that}, that._deselectPoint);
that.seriesGroup.on(eventsConsts.showPointTooltip, {tracker: that}, that._showPointTooltip);
that.seriesGroup.on(eventsConsts.hidePointTooltip, {tracker: that}, that._hidePointTooltip);
that.crossHairOptions = options.crossHairOptions
},
_clean: function() {
var that = this;
that.selectedPoint = that.pointSelectionMode === MULTIPLE_MODE ? [] : null;
that.selectedSeries = that.seriesSelectionMode === MULTIPLE_MODE ? [] : null;
that.hoveredPoint = null;
that.hoveredSeries = null;
that._hideTooltip(that.pointAtShownTooltip);
that._clearTimeouts()
},
_reinit: function(options) {
var that = this;
options = options || {};
if (that.storedSeries !== options.series) {
that.storedSeries = options.series || [];
that._clean()
}
else if (isDefined(that.storedSeries)) {
that._clearPointSelection();
that._clearHover(that);
that._clearTimeouts()
}
that.argumentAxis = options.argumentAxis || [];
that.legendGroup = options.legendGroup;
that.legendCallback = options.legendCallback || $.noop
},
_clearTimeouts: function() {
var that = this,
_clearTimeout = clearTimeout;
_clearTimeout(that.tooltipHoldTimeout);
_clearTimeout(that.cmpCoordTimeout);
_clearTimeout(that.hoverStartTimeOut);
_clearTimeout(that.hoverHoldTimeOut)
},
dispose: function() {
var that = this;
that._clearTimeouts();
clearTimeout(that.unlockMouseTimer);
clearTimeout(that.lockClickTimer);
$.each(that.argumentAxis, function(_, axis) {
axis._axisElementsGroup && axis._axisElementsGroup.off()
});
that.seriesTrackerGroup.off();
that.markerTrackerGroup.off();
that.legendGroup && that.legendGroup.off();
that.seriesGroup.off();
that.rootTracker && that.rootTracker.off();
that.argumentAxis = null;
that.seriesTrackerGroup = null;
that.markerTrackerGroup = null;
that.legendGroup = null;
that.legendCallback = null;
that.seriesGroup = null;
that.crossHairOptions = null;
that.selectedPoint = null;
that.selectedSeries = null;
that.hoveredSeries = null;
that.hoveredPoint = null;
that.storedSeries = null;
that.argumentAxis = null;
that.hoveredObject = null;
that.pointAtShownTooltip = null
},
_prepareMode: function(mode) {
mode = (mode || '').toLowerCase();
return mode = mode !== SINGLE_MODE && mode !== MULTIPLE_MODE ? SINGLE_MODE : mode
},
_prepare: function(typeChart) {
var that = this;
that.rootTracker = that.renderer.getRoot();
$.each(that.argumentAxis, function(_, axis) {
axis._axisElementsGroup && that._eventHandler(axis._axisElementsGroup, {
parser: that._getOptionsAxis,
condition: that._axisCondition,
execute: that._axisEvent
}, {
tracker: that,
axis: axis
})
});
that._eventHandler(that.seriesTrackerGroup, {
parser: that._getOptionsPointSeries,
condition: that._seriesCondition,
execute: that._seriesEvent
}, {tracker: that});
that._eventHandler(that.markerTrackerGroup, {
parser: that._getOptionsPointSeries,
condition: that._pointCondition,
execute: that._pointEvent
}, {tracker: that});
that.legendGroup && that._eventHandler(that.legendGroup, {
parser: that._getLegendData(typeChart),
condition: that._seriesCondition,
execute: that._getLegendEvent(typeChart)
}, {tracker: that});
that._eventHandler(that.rootTracker, {
parser: that._getOptionsCrossHair,
execute: that._crossHairEvent
}, {tracker: that})
},
_getLegendData: function(typeChart) {
return function(event) {
var target = $(event.target),
itemIndex = target.data('itemIndex'),
that = event.data.tracker,
mode = utils.isNumber(itemIndex) && target.data('mode');
if (event.type === 'mousemove')
return [that, event.pageX, event.pageY, event.offsetX, event.offsetY];
if (!utils.isNumber(itemIndex))
return null;
if (typeChart === 'pieChart')
return [that, that.storedSeries[0].getPoints()[itemIndex], mode, event];
else
return [that, that.storedSeries[itemIndex], mode, event]
}
},
_getLegendEvent: function(typeChart) {
var that = this,
legendEvent;
if (typeChart === 'pieChart')
legendEvent = $.extend({}, this._pointEvent, {
touchend: function(that, point, mode, event) {
if (!that.showHoldTooltip)
that._legendClick(that, point, true, event) || that._pointClick(that, point, true, event);
clearTimeout(that.tooltipHoldTimeout);
that._clickLock(that);
that._clearHover(that)
},
click: function(that, point, mode, event) {
that._legendClick(that, point, false, event) || that._pointClick(that, point, false, event)
}
});
else
legendEvent = $.extend({}, this._seriesEvent, {
click: function(that, series, mode, event) {
that._legendClick(that, series, false, event) || that._seriesClick(that, series, false, event)
},
touchend: function(that, series, mode, event) {
that._legendClick(that, series, true, event) || that._seriesClick(that, series, true, event);
that._clickLock(that)
}
});
this.__legendEvent = legendEvent;
return legendEvent
},
_eventHandler: function(group, handlers, data) {
var prepareHandlers = this._designerHandlers(handlers);
group.off(".dxc-tracker");
group.on(prepareHandlers, data)
},
_designerHandlers: function(handler) {
var handlers = {},
parser = handler.parser,
condition = handler.condition,
execute = handler.execute,
designerHandle = function(eventType, func) {
if (condition && condition[eventType] === null)
return;
handlers[eventType + ".dxc-tracker"] = function(event) {
var options = parser ? parser(event) : event;
if (!options)
return;
if (condition && condition[eventType] && condition[eventType].call)
condition[eventType].apply(null, options.concat([func]));
else
func.apply(null, options)
}
};
$.each(execute, designerHandle);
return handlers
},
_getOptionsCrossHair: function(event) {
var that = event.data.tracker;
var rootOffset = utils.getRootOffset(that.renderer);
var xe = event.pageX - rootOffset.left;
var ye = event.pageY - rootOffset.top;
return [that, xe, ye]
},
_getOptionsPointSeries: function(event) {
var object = $(event.target).data('point') || $(event.target).data('series'),
that = event.data.tracker,
mode = object && processMode($(event.target).data('mode') || object.getOptions().hoverMode);
if (event.type === 'mousemove')
return [that, event.pageX, event.pageY, event.offsetX, event.offsetY];
if (!object)
return null;
return [that, object, mode, event]
},
_getOptionsAxis: function(event) {
var that = event.data.tracker,
axis = event.data.axis,
mode = axis.options.hoverMode,
argument;
if (event.target.tagName === "tspan")
argument = $(event.target).parent().data('argument');
else
argument = $(event.target).data('argument');
if (event.type === 'mousemove')
return [that, event.pageX, event.pageY];
if (!axis)
return null;
return [that, axis, mode, argument, event]
},
_pointEvent: {
mouseover: function(that, point, mode) {
if (that.mouseLocked)
return;
that._setHoveredPoint(point, mode);
if (that.tooltipEnabled && point && point.getOptions())
that._compareCoords(that, function() {
that._showTooltip(that.tooltip, point)
})
},
mouseout: function(that, point, mode) {
if (that.mouseLocked)
return;
that._clearHover(that)
},
touchmove: function(that, point, mode) {
clearTimeout(that.tooltipHoldTimeout);
that.tooltipHoldTimeout = null;
that.showHoldTooltip = true
},
mousemove: function(that, pageX, pageY, offsetX, offsetY) {
that._setCurCoords(that, pageX, pageY)
},
touchstart: function(that, point, mode) {
that.showHoldTooltip = false;
that._mouseLock(that);
if (that.tooltipEnabled)
that.tooltipHoldTimeout = setTimeout(function() {
that.showHoldTooltip = true;
that._showTooltip(that.tooltip, point)
}, TOOLTIP_HOLD_TIMEOUT)
},
touchend: function(that, point, mode, event) {
if (!that.showHoldTooltip)
that._pointClick(that, point, true, event);
clearTimeout(that.tooltipHoldTimeout);
that._clickLock(that);
that._clearHover(that)
},
click: function(that, point, mode, event) {
that._pointClick(that, point, false, event)
},
mousedown: function(that, point, mode) {
that._pointEvent.touchstart(that, point, mode)
},
mouseup: function(that, point, mode, event) {
that._pointEvent.touchend(that, point, mode, event)
}
},
_pointCondition: {
mouseover: function(that, point, mode, event, func) {
if (mode === ALL_ARGUMENTS_POINTS_MODE && that.hoveredPoint && that.hoveredPoint.argument === point.argument) {
that.hoverHoldTimeOut = clearTimeout(that.hoverHoldTimeOut);
that.hoveredObject = point;
func(that, point, mode);
return
}
that._setHover(that, point, mode, func)
},
mouseout: function(that, point, mode, event, func) {
that._releaseHover(that, point, mode, func)
},
touchstart: !msPointerEnabled,
touchend: !msPointerEnabled,
mousedown: msPointerEnabled,
mouseup: msPointerEnabled
},
_seriesEvent: {
mouseover: function(that, series, mode) {
if (that.mouseLocked)
return;
that._setHoveredSeries(series, mode)
},
mouseout: function(that, series, mode) {
that._clearHover(that)
},
mousemove: function(that, pageX, pageY, offsetX, offsetY) {
that._setCurCoords(that, pageX, pageY)
},
touchstart: function(that) {
that._mouseLock(that)
},
touchend: function(that, series, _, event) {
that._seriesClick(that, series, true, event);
that._clickLock(that)
},
click: function(that, series, mode, event) {
that._seriesClick(that, series, false, event)
},
mousedown: function(that, point, mode) {
that._seriesEvent.touchstart(that, point, mode)
},
mouseup: function(that, point, mode) {
that._seriesEvent.touchend(that, point, mode)
}
},
_crossHairEvent: {
mousemove: function(that, x, y) {
if (!that.eventType) {
that.eventType = 'mouse';
return
}
else if (that.eventType === 'touch')
return;
else if (that.eventType === 'mouse') {
that._moveCrossHair(that, x, y);
that.eventType = null
}
},
mouseout: function(that) {
that._hideCrossHair(that);
that.eventType = null
},
touchstart: function(that, x, y) {
that.eventType = 'touch'
},
touchend: function(that, x, y) {
that.eventType = null
},
mousedown: function(that, x, y) {
that._crossHairEvent.touchstart(that, x, y)
},
mouseup: function(that, x, y) {
that._crossHairEvent.touchend(that, x, y)
}
},
_hideCrossHair: function(that) {
if (!that.crossHairOptions)
return;
var horizontalLine = that.crossHairOptions.horizontalLine,
verticalLine = that.crossHairOptions.verticalLine;
horizontalLine && horizontalLine.applySettings({visibility: 'hidden'});
verticalLine && verticalLine.applySettings({visibility: 'hidden'})
},
_moveCrossHair: function(that, x, y) {
if (!that.crossHairOptions)
return;
var horizontalLine = that.crossHairOptions.horizontalLine,
verticalLine = that.crossHairOptions.verticalLine,
canvas = that.crossHairOptions.canvas || {};
if (x > canvas.left && x < canvas.width - canvas.right && y > canvas.top && y < canvas.height - canvas.bottom) {
horizontalLine && horizontalLine.applySettings({visibility: 'visible'});
verticalLine && verticalLine.applySettings({visibility: 'visible'});
horizontalLine && horizontalLine.applySettings({translateY: y - canvas.top});
verticalLine && verticalLine.applySettings({translateX: x - canvas.left})
}
else {
horizontalLine && horizontalLine.applySettings({visibility: 'hidden'});
verticalLine && verticalLine.applySettings({visibility: 'hidden'})
}
},
_seriesCondition: {
mouseover: function(that, series, mode, event, func) {
that.hoverStartDelay = 0;
that._setHover(that, series, mode, func)
},
mouseout: function(that, series, mode, event, func) {
that.hoverStartDelay = HOVER_START_DELAY;
that._releaseHover(that, series, mode, func)
},
touchstart: !msPointerEnabled,
touchend: !msPointerEnabled,
mousedown: msPointerEnabled,
mouseup: msPointerEnabled
},
_axisEvent: {
mouseover: function(that, axis, argument) {
if (that.mouseLocked || isDefined(that.hoveredArgument) && that.hoveredArgument === argument)
return;
that._clearHover(that);
if (isDefined(that.hoveredArgument))
that._toAllArgumentPoints(that.hoveredArgument, 'releasePointHoverState');
that._toAllArgumentPoints(argument, 'setPointHoverState');
that.hoveredArgument = argument
},
mouseout: function(that, axis) {
if (that.mouseLocked || !isDefined(that.hoveredArgument))
return;
that._toAllArgumentPoints(that.hoveredArgument, 'releasePointHoverState');
that.hoveredArgument = null
},
mousemove: function(that, pageX, pageY) {
that._setCurCoords(that, pageX, pageY)
},
touchstart: function(that) {
that._mouseLock(that)
},
touchend: function(that, axis, mode, argument, event) {
that._argumentAxisClick(that, axis, argument, true, event);
that._clearHover(that);
that._clickLock(that)
},
click: function(that, axis, mode, argument, event) {
that._clearHover(that);
that._argumentAxisClick(that, axis, argument, false, event)
},
mousedown: function(that) {
that._axisEvent.touchstart(that)
},
mouseup: function(that, axis, mode, argument, event) {
that._axisEvent.touchend(that, axis, mode, argument, event)
}
},
_axisCondition: {
mouseover: function(that, axis, mode, argument, event, func) {
that._hideCrossHair(that);
if (mode === ALL_ARGUMENTS_POINTS_MODE)
that._setHover(that, axis, argument, func)
},
mouseout: function(that, axis, mode, argument, event, func) {
that._releaseHover(that, axis, argument, func)
},
touchstart: !msPointerEnabled,
touchend: !msPointerEnabled,
mousedown: msPointerEnabled,
mouseup: msPointerEnabled
},
_setHover: function(that, object, mode, func) {
if (object === that.hoveredObject) {
that.hoverHoldTimeOut = clearTimeout(that.hoverHoldTimeOut);
if (mode === object.lastHoverMode)
return
}
if (that.mouseLocked)
return;
clearTimeout(that.cmpCoordTimeout);
clearTimeout(that.hoverStartTimeOut);
that.hoverStartTimeOut = setTimeout(function() {
clearTimeout(that.hoverHoldTimeOut);
that.hoveredObject = object;
func(that, object, mode)
}, that.hoverStartDelay)
},
_releaseHover: function(that, object, mode, func) {
if (that.mouseLocked)
return;
clearTimeout(that.cmpCoordTimeout);
clearTimeout(that.hoverStartTimeOut);
if (object === that.hoveredObject)
that.hoverHoldTimeOut = setTimeout(function() {
that.hoveredObject = null;
func(that, object, mode);
that.hoverStartDelay = 0
}, HOVER_HOLD_DELAY)
},
_compareCoords: function(that, func) {
clearTimeout(that.cmpCoordTimeout);
if (Math.abs(that.pX - that.cX) + Math.abs(that.pY - that.cY) < that.sensitivity) {
if (that.mouseLocked)
return;
func()
}
else {
that.pX = that.cX;
that.pY = that.cY;
that.cmpCoordTimeout = setTimeout(function() {
that._compareCoords(that, func)
}, that.hoverStartDelay === 0 ? HOVER_START_DELAY : 0)
}
},
_seriesClick: function(that, series, touchEvent, event) {
if (that.lockClick && !touchEvent)
return;
that.seriesClick && that.seriesClick.call(series, series, event)
},
_legendClick: function(that, series, touchEvent, event) {
var legendClick = that.legendClick;
if (that.lockClick && !touchEvent)
return true;
if (legendClick) {
legendClick.call(series, series, event);
return true
}
return false
},
_pointClick: function(that, point, touchEvent, event) {
var series = point.series;
if (that.lockClick && !touchEvent)
return;
if (that.pointClick) {
that.pointClick.call(point, point, event);
return
}
that.seriesClick && that.seriesClick.call(series, series, event);
return
},
_argumentAxisClick: function(that, axis, argument, touchEvent, event) {
if (that.lockClick && !touchEvent)
return;
that.argumentAxisClick && that.argumentAxisClick.call(axis, axis, argument, event)
},
_selectSeries: function(event, mode) {
event.data.tracker._setSelectedSeries(event.target, mode)
},
_deselectSeries: function(event, mode) {
event.data.tracker._releaseSelectedSeries(event.target, mode)
},
_selectPoint: function(event, point) {
event.data.tracker._setSelectedPoint(point)
},
_deselectPoint: function(event, point) {
event.data.tracker._releaseSelectedPoint(point)
},
_showPointTooltip: function(event, point) {
var that = event.data.tracker;
that._showTooltip(that.tooltip, point)
},
_hidePointTooltip: function(event, point) {
event.data.tracker._hideTooltip(point)
},
_hideTooltip: function(point) {
var tooltip = this && this.tooltip;
if (!tooltip || point && this.pointAtShownTooltip !== point)
return;
point = point || this.pointAtShownTooltip;
tooltip.hide();
if (this.pointAtShownTooltip) {
this.pointAtShownTooltip = null;
isFunction(this.tooltipHidden) && this.tooltipHidden.call(point, point)
}
},
_showTooltip: function(tooltip, point) {
var tooltipFormatObject = point.getTooltipFormatObject(tooltip);
if (!isDefined(tooltipFormatObject.valueText) && !tooltipFormatObject.points || !point.isVisible())
return;
this.pointAtShownTooltip && this._hideTooltip(this.pointAtShownTooltip);
if (point && point.getOptions()) {
var tooltipCoords = point.getTooltipCoords();
if (!tooltip.prepare(tooltipFormatObject, {
x: tooltipCoords.x,
y: tooltipCoords.y,
offset: tooltipCoords.offset
}))
return;
tooltip.show();
!this.pointAtShownTooltip && isFunction(this.tooltipShown) && this.tooltipShown.call(point, point);
this.pointAtShownTooltip = point
}
},
_setHoveredSeries: function(series, mode) {
var that = this;
if (mode !== NONE_MODE && that.hoveredSeries !== series || series.lastHoverMode !== mode) {
that._clearHover(that);
that.hoveredSeries = series;
series.setHoverState(mode, that.legendCallback(series));
that.seriesHover && that.seriesHover.call(series, series);
that.seriesHoverChanged && that.seriesHoverChanged.call(series, series)
}
if (mode === NONE_MODE)
$(series).trigger('NoneMode')
},
_setSelectedSeries: function(series, mode) {
var that = this,
seriesContain = false;
if (this.seriesSelectionMode === MULTIPLE_MODE)
$.each(that.selectedSeries, function(_, sr) {
if (sr == series) {
seriesContain = true;
return false
}
});
else if (that.selectedSeries == series)
seriesContain = true;
if (!seriesContain || series.lastSelectionMode !== mode) {
if (that.seriesSelectionMode === SINGLE_MODE) {
this._releaseSelectedSeries();
that.selectedSeries = series
}
else
that.selectedSeries.push(series);
series.setSelectedState(mode, that.legendCallback(series));
that.seriesSelected && that.seriesSelected.call(series, series);
that.seriesSelectionChanged && that.seriesSelectionChanged.call(series, series)
}
},
_setHoveredPoint: function(point, mode) {
var that = this;
var debug = DX.utils.debug;
debug.assert(point.series, 'series was not assigned to point or empty');
if (that.hoveredPoint === point && !point.series)
return;
that._clearHover(that);
that.hoveredPoint = point;
if (point && point.getOptions())
that._setHoverStylePointWithMode(point, 'setPointHoverState', mode || processMode(point.getOptions().hoverMode), that.pointHoverChanged, that.legendCallback(point));
that.pointHover && that.pointHover.call(point, point)
},
_toAllArgumentPoints: function(argument, func, callBack) {
var that = this;
$.each(that.storedSeries, function(_, series) {
var neighborPoint = series.getPointByArg(argument);
if (neighborPoint) {
series[func](neighborPoint);
callBack && callBack.call(neighborPoint, neighborPoint)
}
})
},
_setHoverStylePointWithMode: function(point, func, mode, callBack, legendCallback) {
var that = this;
switch (mode) {
case ALL_ARGUMENTS_POINTS_MODE:
this._toAllArgumentPoints(point.argument, func, callBack);
break;
case ALL_SERIES_POINTS_MODE:
$.each(point.series.getPoints(), function(_, point) {
point.series[func](point);
callBack && callBack.call(point, point)
});
break;
case NONE_MODE:
break;
default:
point.series[func](point, legendCallback);
callBack && callBack.call(point, point)
}
},
_setSelectedPoint: function(point) {
var that = this,
pointContain = false;
if (this.pointSelectionMode === MULTIPLE_MODE) {
$.each(that.selectedPoint, function(_, pt) {
if (pt == point) {
pointContain = true;
return false
}
});
!pointContain && that.selectedPoint.push(point)
}
else if (that.selectedPoint !== point) {
this._releaseSelectedPoint();
that.selectedPoint = point
}
else
pointContain = true;
if (!pointContain) {
that._setHoverStylePointWithMode(point, 'setPointSelectedState', processMode(point.getOptions().selectionMode), that.pointSelectionChanged, that.legendCallback(point));
that.pointSelected && that.pointSelected.call(point, point)
}
},
_releaseHoveredSeries: function() {
var that = this;
if (!that.hoveredSeries)
return;
that.hoveredSeries.releaseHoverState(undefined, that.legendCallback(that.hoveredSeries));
that.seriesHoverChanged && that.seriesHoverChanged.call(that.hoveredSeries, that.hoveredSeries);
that.hoveredSeries = null
},
_releaseSelectedSeriesMultiMode: function(series) {
var that = this;
if (!that.selectedSeries)
return;
series.releaseSelectedState(undefined, that.legendCallback(series));
that.seriesSelectionChanged && that.seriesSelectionChanged.call(series, series);
that.selectedSeries = $.map(that.selectedSeries, function(sr) {
if (sr !== series)
return sr
})
},
_releaseSelectedSeriesSingleMode: function() {
var that = this,
series = this.selectedSeries;
if (!series)
return;
series.releaseSelectedState(undefined, that.legendCallback(series));
that.seriesSelectionChanged && that.seriesSelectionChanged.call(series, series);
that.selectedSeries = null
},
_releaseHoveredPoint: function() {
var that = this,
point = that.hoveredPoint,
mode;
if (!point || !point.getOptions())
return;
mode = processMode(point.getOptions().hoverMode);
if (mode === ALL_SERIES_POINTS_MODE)
$.each(point.series.getPoints(), function(_, point) {
point.series.releasePointHoverState(point);
that.pointHoverChanged && that.pointHoverChanged.call(point, point)
});
else if (mode === ALL_ARGUMENTS_POINTS_MODE)
that._toAllArgumentPoints(point.argument, 'releasePointHoverState', that.pointHoverChanged);
else {
point.releaseHoverState(that.legendCallback(point));
that.pointHoverChanged && that.pointHoverChanged.call(point, point)
}
if (that.tooltipEnabled && !that.showHoldTooltip)
that._hideTooltip(point);
that.hoveredPoint = null
},
_releaseSelectedPointMultiMode: function(point) {
var that = this,
points = that.selectedPoint;
if (!points)
return;
that._setHoverStylePointWithMode(point, 'releasePointSelectedState', processMode(point.getOptions().selectionMode), that.pointSelectionChanged, that.legendCallback(point));
this.selectedPoint = $.map(this.selectedPoint, function(pt) {
if (pt !== point)
return pt
})
},
_releaseSelectedPointSingleMode: function() {
var that = this,
point = that.selectedPoint;
if (!point)
return;
that._setHoverStylePointWithMode(point, 'releasePointSelectedState', processMode(point.getOptions().selectionMode), that.pointSelectionChanged, that.legendCallback(point));
this.selectedPoint = null
},
_clearPointSelection: function() {
var that = this;
if (that.pointSelectionMode === SINGLE_MODE)
that._releaseSelectedPoint();
else
$.each(that.selectedPoint || [], function(_, point) {
that._releaseSelectedPoint(point)
})
},
clearSelection: function() {
var that = this;
that._clearPointSelection();
if (that.seriesSelectionMode === SINGLE_MODE)
that._releaseSelectedSeries();
else
$.each(that.selectedSeries, function(_, series) {
that._releaseSelectedSeries(series)
})
},
setTooltip: function(tooltip) {
this.tooltip = tooltip
},
_mouseLock: function(tracker) {
if (tracker.unlockMouseTimer)
clearTimeout(tracker.unlockMouseTimer);
tracker.mouseLocked = true;
tracker.unlockMouseTimer = setTimeout(function() {
tracker.mouseLocked = false
}, MOUSE_EVENT_LOCK_TIMEOUT)
},
_clickLock: function(tracker) {
tracker.lockClick = true;
if (tracker.lockClickTimer)
clearTimeout(tracker.lockClickTimer);
tracker.lockClickTimer = setTimeout(function() {
tracker.lockClick = false
}, CLICK_EVENT_LOCK_TIMEOUT)
},
_setCurCoords: function(that, pageX, pageY) {
that.cX = pageX;
that.cY = pageY
},
_clearHover: function(that) {
that._releaseHoveredSeries();
that._releaseHoveredPoint()
}
})
})(jQuery, DevExpress);
/*! Module viz-charts, file dxChart.js */
(function($, DX, undefined) {
var ui = DX.ui,
viz = DX.viz;
DX.registerComponent("dxChart", viz.charts.Chart)
})(jQuery, DevExpress);
/*! Module viz-charts, file dxPieChart.js */
(function($, DX, undefined) {
var ui = DX.ui,
viz = DX.viz;
DX.registerComponent("dxPieChart", viz.charts.PieChart)
})(jQuery, DevExpress);
DevExpress.MOD_VIZ_CHARTS = true
}
if (!DevExpress.MOD_VIZ_GAUGES) {
if (!DevExpress.MOD_VIZ_CORE)
throw Error('Required module is not referenced: viz-core');
/*! Module viz-gauges, file namespaces.js */
(function(DX) {
DX.viz.gauges = {__internals: {
circularNeedles: {},
circularMarkers: {},
linearNeedles: {},
linearMarkers: {}
}};
DX.viz.gauges.__tests = {}
})(DevExpress);
/*! Module viz-gauges, file factory.js */
(function(DX, $, undefined) {
var internals = DX.viz.gauges.__internals,
circularNeedles = internals.circularNeedles,
circularMarkers = internals.circularMarkers,
linearNeedles = internals.linearNeedles,
linearMarkers = internals.linearMarkers;
var _String = window.String,
_isString = DX.utils.isString;
DX.viz.gauges.__factory = {
createCircularValueIndicator: function(type) {
var indicatorType = circularNeedles.RectangleNeedle;
switch (_String(type).toLowerCase()) {
case'rectangleneedle':
case'rectangle':
indicatorType = circularNeedles.RectangleNeedle;
break;
case'triangleneedle':
case'triangle':
indicatorType = circularNeedles.TriangleNeedle;
break;
case'twocolorneedle':
case'twocolorrectangle':
indicatorType = circularNeedles.TwoColorRectangleNeedle;
break;
case'rangebar':
indicatorType = internals.CircularRangeBar;
break
}
return new indicatorType
},
createLinearValueIndicator: function(type) {
var indicatorType = internals.LinearRangeBar;
switch (_String(type).toLowerCase()) {
case'rectangle':
indicatorType = linearNeedles.RectangleNeedle;
break;
case'rhombus':
indicatorType = linearNeedles.RhombusNeedle;
break;
case'circle':
indicatorType = linearNeedles.CircleNeedle;
break;
case'rangebar':
indicatorType = internals.LinearRangeBar;
break
}
return new indicatorType
},
createCircularSubvalueIndicator: function(type) {
var indicatorType = circularMarkers.TriangleMarker;
switch (_String(type).toLowerCase()) {
case'trianglemarker':
case'triangle':
indicatorType = circularMarkers.TriangleMarker;
break;
case'textcloud':
indicatorType = circularMarkers.TextCloudMarker;
break
}
return new indicatorType
},
createLinearSubvalueIndicator: function(type) {
var indicatorType = linearMarkers.TriangleMarker;
switch (_String(type).toLowerCase()) {
case'trianglemarker':
case'triangle':
indicatorType = linearMarkers.TriangleMarker;
break;
case'textcloud':
indicatorType = linearMarkers.TextCloudMarker;
break
}
return new indicatorType
},
createCircularValueIndicatorInHardMode: function(type) {
var indicatorType = null;
switch (_String(type).toLowerCase()) {
case'rectangleneedle':
indicatorType = circularNeedles.RectangleNeedle;
break;
case'triangleneedle':
indicatorType = circularNeedles.TriangleNeedle;
break;
case'twocolorneedle':
indicatorType = circularNeedles.TwoColorRectangleNeedle;
break;
case'rangebar':
indicatorType = internals.CircularRangeBar;
break;
case'trianglemarker':
indicatorType = circularMarkers.TriangleMarker;
break;
case'textcloud':
indicatorType = circularMarkers.TextCloudMarker;
break
}
return indicatorType ? new indicatorType : null
},
createLinearValueIndicatorInHardMode: function(type) {
var indicatorType = null;
switch (_String(type).toLowerCase()) {
case'rectangle':
indicatorType = linearNeedles.RectangleNeedle;
break;
case'rhombus':
indicatorType = linearNeedles.RhombusNeedle;
break;
case'circle':
indicatorType = linearNeedles.CircleNeedle;
break;
case'rangebar':
indicatorType = internals.LinearRangeBar;
break;
case'trianglemarker':
indicatorType = linearMarkers.TriangleMarker;
break;
case'textcloud':
indicatorType = linearMarkers.TextCloudMarker;
break
}
return indicatorType ? new indicatorType : null
},
createCircularNeedle: function(type) {
switch (_String(type).toLowerCase()) {
case'rectangleneedle':
case'rectangle':
return new circularNeedles.RectangleNeedle;
case'twocolorneedle':
case'twocolorrectangle':
return new circularNeedles.TwoColorRectangleNeedle;
case'triangleneedle':
case'triangle':
return new circularNeedles.TriangleNeedle;
case'rangebar':
return new internals.CircularRangeBar
}
return undefined
},
createLinearNeedle: function(type) {
switch (_String(type).toLowerCase()) {
case'rectangle':
return new linearNeedles.RectangleNeedle;
case'rhombus':
return new linearNeedles.RhombusNeedle;
case'circle':
return new linearNeedles.CircleNeedle;
case'rangebar':
return new internals.LinearRangeBar
}
return undefined
},
createCircularMarker: function(type) {
switch (_String(type).toLowerCase()) {
case'trianglemarker':
case'triangle':
return new circularMarkers.TriangleMarker;
case'textcloud':
return new circularMarkers.TextCloudMarker
}
return undefined
},
createLinearMarker: function(type) {
switch (_String(type).toLowerCase()) {
case'trianglemarker':
case'triangle':
return new linearMarkers.TriangleMarker;
case'textcloud':
return new linearMarkers.TextCloudMarker
}
return undefined
},
createCircularRangeBar: function(parameters) {
return new internals.CircularRangeBar(parameters)
},
createLinearRangeBar: function(parameters) {
return new internals.LinearRangeBar(parameters)
},
createCircularScale: function(parameters) {
return new internals.CircularScale(parameters)
},
createLinearScale: function(parameters) {
return new internals.LinearScale(parameters)
},
createCircularRangeContainer: function(parameters) {
return new internals.CircularRangeContainer(parameters)
},
createLinearRangeContainer: function(parameters) {
return new internals.LinearRangeContainer(parameters)
},
createTitle: function(parameters) {
return new internals.Title(parameters)
},
createIndicator: function() {
return internals.Indicator && new internals.Indicator || null
},
createLayoutManager: function() {
return new internals.LayoutManager
},
createThemeManager: function(options) {
return new internals.ThemeManager(options)
},
createTracker: function(parameters) {
return new internals.Tracker(parameters)
}
};
var _isFunction = DX.utils.isFunction,
_String = window.String,
_extend = $.extend;
var _formatHelper = DX.formatHelper;
internals.formatValue = function(value, options, extra) {
options = options || {};
var text = _formatHelper.format(value, options.format, options.precision),
context;
if (_isFunction(options.customizeText)) {
var context = _extend({
value: value,
valueText: text
}, extra);
return _String(options.customizeText.call(context, context))
}
return text
};
internals.getSampleText = function(translator, options) {
var text1 = internals.formatValue(translator.getDomainStart(), options),
text2 = internals.formatValue(translator.getDomainEnd(), options);
return text1.length >= text2.length ? text1 : text2
}
})(DevExpress, jQuery);
/*! Module viz-gauges, file scale.js */
(function(DX, $, undefined) {
var _Number = Number,
_String = String,
_isFinite = isFinite,
_min = Math.min,
_max = Math.max,
_abs = Math.abs,
_atan = Math.atan,
_acos = Math.acos,
_ceil = Math.ceil,
_isFunction = DX.utils.isFunction,
_isArray = DX.utils.isArray,
_getCosAndSin = DX.utils.getCosAndSin,
_normalizeAngle = DX.utils.normalizeAngle,
_convertAngleToRendererSpace = DX.utils.convertAngleToRendererSpace,
_map = $.map;
var _formatHelper = DX.formatHelper,
_tickProvider = DX.viz.core.tickProvider;
var PI_DIV_180 = Math.PI / 180;
function binarySearch(x, list) {
var a = 0,
b = list.length - 1,
flag = list[a] - list[b] < 0,
c,
k = -1;
if (list[a] === x)
k = a;
if (list[b] === x)
k = b;
while (k < 0 && a <= b) {
c = ~~((a + b) / 2);
if (list[c] === x)
k = c;
else if (list[c] - x < 0 === flag)
a = c + 1;
else
b = c - 1
}
return k
}
function sortAsc(x, y) {
return x - y
}
function sortDes(x, y) {
return y - x
}
DX.viz.gauges.__internals.BaseScale = DX.Class.inherit({
ctor: function(parameters) {
var that = this;
that._renderer = parameters.renderer;
that._container = parameters.container;
that._translator = parameters.translator;
that._root = that._renderer.createGroup({'class': 'dxg-scale'});
that._majorTicks = that._renderer.createGroup({'class': 'dxg-major-ticks'});
that._minorTicks = that._renderer.createGroup({'class': 'dxg-minor-ticks'});
that._labels = that._renderer.createGroup({'class': 'dxg-labels'})
},
dispose: function() {
var that = this;
that._renderer = that._container = that._renderer = that._root = that._majorTicks = that._minorTicks = that._labels = null;
return that
},
clean: function() {
var that = this;
that._root.detach();
that._majorTicks.detach().clear();
that._minorTicks.detach().clear();
that._labels.detach().clear();
that._majorTicksEnabled = that._minorTicksEnabled = that._labelsEnabled = that._options = that.enabled = null;
return that
},
render: function(options) {
var that = this;
that._options = options;
that._processOptions(options);
if (that._majorTicksEnabled || that._minorTicksEnabled || that._labelsEnabled) {
that.enabled = true;
that._root.append(that._container);
if (that._majorTicksEnabled)
that._majorTicks.append(that._root);
if (that._minorTicksEnabled)
that._minorTicks.append(that._root);
if (that._labelsEnabled) {
that._labels.append(that._root);
that._measureText()
}
}
return that
},
_processOptions: function(options) {
var that = this;
that._majorTicksEnabled = options.majorTick.visible && options.majorTick.length > 0 && options.majorTick.width > 0;
that._minorTicksEnabled = options.minorTick.visible && options.minorTick.length > 0 && options.minorTick.width > 0;
that._labelsEnabled = options.label.visible && _Number(options.label.indentFromTick) !== 0;
that._setupOrientation()
},
_getSampleText: function() {
var that = this,
domain = that._translator.getDomain(),
texts = [],
i,
ii,
text,
maxLength = 0,
maxText = '';
var ticks = _tickProvider.getTicks({
min: domain[0],
max: domain[1],
tickInterval: that._options.majorTick.tickInterval > 0 ? _Number(that._options.majorTick.tickInterval) : undefined,
screenDelta: that._options.approximateScreenDelta,
gridSpacingFactor: that._getGridSpacingFactor().majorTicks
});
for (i = 0, ii = ticks.length; i < ii; ++i) {
text = that._formatValue(ticks[i]);
text.length > maxLength && (maxText = text) && (maxLength = text.length)
}
return maxText
},
_measureText: function() {
var that = this,
value = that._getSampleText(),
text = that._renderer.createText(value, 0, 0, {font: that._options.label.font}).append(that._labels),
bbox = text.getBBox();
text.remove();
that._textVerticalOffset = -bbox.y - bbox.height / 2;
that._textWidth = bbox.width;
that._textHeight = bbox.height;
that._textLength = value.length
},
_formatValue: function(value) {
var options = this._options.label,
text = _formatHelper.format(value, options.format, options.precision);
if (_isFunction(options.customizeText)) {
text = {
value: value,
valueText: text
};
text = _String(options.customizeText.call(text, text))
}
return text
},
_setupOrientation: null,
_getCustomValues: function(values, compare) {
var translator = this._translator,
result = [];
if (_isArray(values)) {
result = _map(values, function(x) {
return _isFinite(translator.translate(x)) ? _Number(x) : null
}).sort(compare);
result = _map(result, function(x, i) {
return x !== result[i - 1] ? x : null
})
}
return result
},
_generateTicks: function(layout) {
var that = this,
majorTicksOptions = {
tickInterval: that._options.majorTick.tickInterval > 0 ? _Number(that._options.majorTick.tickInterval) : undefined,
gridSpacingFactor: that._getGridSpacingFactor().majorTicks,
numberMultipliers: [1, 2, 5]
},
minorTicksOptions = {
tickInterval: that._options.minorTick.tickInterval > 0 ? _Number(that._options.minorTick.tickInterval) : undefined,
gridSpacingFactor: that._getGridSpacingFactor().minorTicks,
numberMultipliers: [1, 2, 5]
};
if (that._options.majorTick.useTicksAutoArrangement) {
majorTicksOptions.useTicksAutoArrangement = true;
majorTicksOptions.renderer = that._renderer;
majorTicksOptions.translator = that._translator;
majorTicksOptions.getCustomAutoArrangementStep = function(values) {
return that._getCuttingFactor(values.length, {
width: that._textWidth,
height: that._textHeight
}, layout)
}
}
return _tickProvider.getFullTicks(that._translator.getDomain()[0], that._translator.getDomain()[1], that._getScreenDelta(layout), majorTicksOptions, minorTicksOptions)
},
_getTicks: function(layout) {
var that = this,
compareCallback = that._translator.getDomain()[0] < that._translator.getDomain()[1] ? sortAsc : sortDes,
info = that._generateTicks(layout);
var majorValues = that._options.majorTick.showCalculatedTicks ? info.majorTicks : [];
var customMajorValues = that._getCustomValues(that._options.majorTick.customTickValues, compareCallback);
customMajorValues = _map(customMajorValues, function(value) {
return binarySearch(value, majorValues) === -1 ? value : null
});
var minorValues = that._options.minorTick.showCalculatedTicks ? info.minorTicks : [];
minorValues = _map(minorValues, function(value) {
return binarySearch(value, customMajorValues) === -1 ? value : null
});
var customMinorValues = that._getCustomValues(that._options.minorTick.customTickValues, compareCallback);
var list = majorValues.concat(minorValues, customMajorValues).sort(compareCallback);
customMinorValues = _map(customMinorValues, function(value) {
return binarySearch(value, list) === -1 ? value : null
});
return {
major: _map(majorValues.concat(customMajorValues), function(value) {
return {
value: value,
position: that._translator.translate(value)
}
}),
minor: _map(minorValues.concat(customMinorValues), function(value) {
return {
value: value,
position: that._translator.translate(value)
}
})
}
},
_createMajorTicks: function(ticks, layout) {
var that = this;
that._majorTicks.clear().applySettings({fill: that._options.majorTick.color});
var points = that._getTickPoints(_Number(that._options.majorTick.length), _Number(that._options.majorTick.width), layout);
if (points) {
var i = 0,
ii = ticks.length,
element;
that._options.hideFirstTick && ++i;
that._options.hideLastTick && --ii;
for (; i < ii; ++i) {
element = that._renderer.createArea(points);
that._moveTick(element, ticks[i], layout);
element.append(that._majorTicks)
}
}
},
_createMinorTicks: function(ticks, layout) {
var that = this;
that._minorTicks.clear().applySettings({fill: that._options.minorTick.color});
var points = that._getTickPoints(_Number(that._options.minorTick.length), _Number(that._options.minorTick.width), layout);
if (points) {
var i = 0,
ii = ticks.length,
element;
for (; i < ii; ++i) {
element = that._renderer.createArea(points);
that._moveTick(element, ticks[i], layout);
element.append(that._minorTicks)
}
}
},
_createLabels: function(ticks, layout) {
var that = this,
indentFromTick = _Number(that._options.label.indentFromTick);
that._labels.clear().applySettings({
align: that._getLabelAlign(indentFromTick),
font: that._options.label.font
});
var textPosition = that._getLabelPosition(that._majorTicksEnabled ? _Number(that._options.majorTick.length) : 0, indentFromTick, layout);
if (textPosition) {
var i = 0,
ii = ticks.length,
points,
text;
that._options.hideFirstLabel && ++i;
that._options.hideLastLabel && --ii;
for (; i < ii; ++i) {
text = that._formatValue(ticks[i].value);
points = that._getLabelOptions(text, textPosition, indentFromTick, ticks[i], layout);
that._renderer.createText(text, points.x, points.y + that._textVerticalOffset).append(that._labels)
}
}
},
resize: function(layout) {
var that = this,
ticks = that._getTicks(layout);
if (that._majorTicksEnabled)
that._createMajorTicks(ticks.major, layout);
if (that._minorTicksEnabled)
that._createMinorTicks(ticks.minor, layout);
if (that._labelsEnabled)
that._createLabels(ticks.major, layout);
return that
}
});
function getBasedAngle(startAngle, endAngle) {
var startDelta,
endDelta,
tmp;
if (startAngle > endAngle) {
tmp = endAngle;
endAngle = startAngle;
startAngle = tmp
}
startDelta = 0 <= startAngle && startAngle <= 180 ? _abs(90 - startAngle) : _abs(270 - startAngle);
startDelta = startAngle < 90 && 90 < endAngle || startAngle < 270 && 270 < endAngle ? 0 : startDelta;
endDelta = 0 < endAngle && endAngle < 180 ? _abs(90 - endAngle) : _abs(270 - endAngle);
return startDelta < endDelta ? startDelta : endDelta
}
DX.viz.gauges.__internals.CircularScale = DX.viz.gauges.__internals.BaseScale.inherit({
_getGridSpacingFactor: function() {
return {
majorTicks: 17,
minorTicks: 5
}
},
_getScreenDelta: function(layout) {
return (this._translator.getCodomainStart() - this._translator.getCodomainEnd()) * layout.radius * PI_DIV_180
},
_getCuttingFactor: function(ticksCount, maxLabelSize, layout) {
var that = this,
options = that._options,
startAngle = that._translator.getCodomainStart(),
endAngle = that._translator.getCodomainEnd(),
radius = that._getLabelPosition(that._majorTicksEnabled ? _Number(that._options.majorTick.length) : 0, _Number(that._options.label.indentFromTick), layout),
baseAngle = getBasedAngle(_normalizeAngle(startAngle), _normalizeAngle(endAngle)),
baseAngleCosSin = _getCosAndSin(baseAngle),
degreesPerTick = (startAngle - endAngle) / ticksCount,
minAngleBetweenTicks,
widthBasedAngle,
tanOfWidthBasedAngle,
heightBasedAngle,
cosOfHeightBasedAngle,
cuttingBackFactor = 1;
tanOfWidthBasedAngle = (baseAngleCosSin.sin * radius + maxLabelSize.width) / (baseAngleCosSin.cos * radius);
widthBasedAngle = _abs(baseAngle - _atan(tanOfWidthBasedAngle) / PI_DIV_180);
cosOfHeightBasedAngle = baseAngleCosSin.cos - maxLabelSize.height / radius;
heightBasedAngle = -1 > cosOfHeightBasedAngle || cosOfHeightBasedAngle > 1 ? 90 : _abs(baseAngle - _acos(cosOfHeightBasedAngle) / PI_DIV_180);
minAngleBetweenTicks = widthBasedAngle < heightBasedAngle ? widthBasedAngle : heightBasedAngle;
if (degreesPerTick < minAngleBetweenTicks)
cuttingBackFactor = _ceil(minAngleBetweenTicks / degreesPerTick);
return _max(1, cuttingBackFactor)
},
_setupOrientation: function() {
var that = this;
that._inner = that._outer = 0;
switch (that._options.orientation) {
case'inside':
that._inner = 1;
break;
case'center':
that._inner = that._outer = 0.5;
break;
default:
that._outer = 1;
break
}
},
_getTickPoints: function(length, width, layout) {
var x1 = layout.x - width / 2,
x2 = layout.x + width / 2,
y1 = layout.y - layout.radius - length * this._outer,
y2 = layout.y - layout.radius + length * this._inner;
return y1 > 0 && y2 > 0 ? [x1, y1, x2, y1, x2, y2, x1, y2] : null
},
_moveTick: function(element, tick, layout) {
element.rotate(_convertAngleToRendererSpace(tick.position), layout.x, layout.y)
},
_getLabelPosition: function(tickLength, textIndent, layout) {
var position = layout.radius + tickLength * (textIndent >= 0 ? this._outer : -this._inner) + textIndent;
return position > 0 ? position : null
},
_getLabelAlign: function() {
return 'center'
},
_getLabelOptions: function(textValue, textPosition, textIndent, tick, layout) {
var cossin = _getCosAndSin(tick.position),
x = layout.x + cossin.cos * textPosition,
y = layout.y - cossin.sin * textPosition,
dx = cossin.cos * (textValue.length / this._textLength) * this._textWidth / 2,
dy = cossin.sin * this._textHeight / 2;
if (textIndent > 0) {
x += dx;
y -= dy
}
else {
x -= dx;
y += dy
}
return {
x: x,
y: y
}
},
measure: function(layout) {
var that = this,
result = {
min: layout.radius,
max: layout.radius
};
if (that._majorTicksEnabled) {
result.min = _min(result.min, layout.radius - that._inner * that._options.majorTick.length);
result.max = _max(result.max, layout.radius + that._outer * that._options.majorTick.length)
}
if (that._minorTicksEnabled) {
result.min = _min(result.min, layout.radius - that._inner * that._options.minorTick.length);
result.max = _max(result.max, layout.radius + that._outer * that._options.minorTick.length)
}
if (that._labelsEnabled) {
if (that._options.label.indentFromTick > 0) {
result.horizontalOffset = _Number(that._options.label.indentFromTick) + that._textWidth;
result.verticalOffset = _Number(that._options.label.indentFromTick) + that._textHeight
}
else {
result.horizontalOffset = result.verticalOffset = 0;
result.min -= -_Number(that._options.label.indentFromTick) + _max(that._textWidth, that._textHeight)
}
result.inverseHorizontalOffset = that._textWidth / 2;
result.inverseVerticalOffset = that._textHeight / 2
}
return result
}
});
DX.viz.gauges.__internals.LinearScale = DX.viz.gauges.__internals.BaseScale.inherit({
_getGridSpacingFactor: function() {
return {
majorTicks: 25,
minorTicks: 5
}
},
_getScreenDelta: function(layout) {
return _abs(this._translator.getCodomainEnd() - this._translator.getCodomainStart())
},
_getCuttingFactor: function(ticksCount, maxLabelSize, layout) {
var that = this,
labelSize = that.vertical ? maxLabelSize.height : maxLabelSize.width,
screenSize = _abs(that._translator.getCodomainEnd() - that._translator.getCodomainStart());
return _max(1, _ceil(ticksCount * labelSize / (screenSize + labelSize)))
},
_setupOrientation: function() {
var that = this;
that.vertical = that._options.vertical;
that._inner = that._outer = 0;
if (that.vertical)
switch (that._options.horizontalOrientation) {
case'left':
that._inner = 1;
break;
case'center':
that._inner = that._outer = 0.5;
break;
default:
that._outer = 1;
break
}
else
switch (that._options.verticalOrientation) {
case'top':
that._inner = 1;
break;
case'middle':
that._inner = that._outer = 0.5;
break;
default:
that._outer = 1;
break
}
},
_getTickPoints: function(length, width, layout) {
var that = this,
x1,
x2,
y1,
y2;
if (that.vertical) {
x1 = layout.x - length * that._inner;
x2 = layout.x + length * that._outer;
y1 = -width / 2;
y2 = +width / 2
}
else {
x1 = -width / 2;
x2 = +width / 2;
y1 = layout.y - length * that._inner;
y2 = layout.y + length * that._outer
}
return [x1, y1, x2, y1, x2, y2, x1, y2]
},
_moveTick: function(element, tick, layout) {
var x = 0,
y = 0;
if (this.vertical)
y = tick.position;
else
x = tick.position;
element.move(x, y)
},
_getLabelPosition: function(tickLength, textIndent, layout) {
var position = tickLength * (textIndent >= 0 ? this._outer : -this._inner) + textIndent;
if (this.vertical)
position += layout.x;
else
position += layout.y + (textIndent >= 0 ? 1 : -1) * this._textVerticalOffset;
return position
},
_getLabelAlign: function(textIndent) {
return this.vertical ? textIndent > 0 ? 'left' : 'right' : 'center'
},
_getLabelOptions: function(textValue, textPosition, textIndent, tick, layout) {
var x,
y;
if (this.vertical) {
x = textPosition;
y = tick.position
}
else {
x = tick.position;
y = textPosition
}
return {
x: x,
y: y
}
},
measure: function(layout) {
var that = this,
p = layout[that.vertical ? 'x' : 'y'],
result = {
min: p,
max: p
};
if (that._majorTicksEnabled) {
result.min = _min(result.min, p - that._inner * that._options.majorTick.length);
result.max = _max(result.max, p + that._outer * that._options.majorTick.length)
}
if (that._minorTicksEnabled) {
result.min = _min(result.min, p - that._inner * that._options.minorTick.length);
result.max = _max(result.max, p + that._outer * that._options.minorTick.length)
}
if (that._labelsEnabled) {
if (that._options.label.indentFromTick > 0)
result.max += +_Number(that._options.label.indentFromTick) + that[that.vertical ? '_textWidth' : '_textHeight'];
else
result.min -= -_Number(that._options.label.indentFromTick) + that[that.vertical ? '_textWidth' : '_textHeight'];
result.indent = that[that.vertical ? '_textHeight' : '_textWidth'] / 2
}
return result
}
})
})(DevExpress, jQuery);
/*! Module viz-gauges, file baseIndicator.js */
(function(DX, $, undefined) {
var _isFinite = isFinite,
_Number = Number,
_extend = $.extend;
DX.viz.gauges.__internals.BaseIndicator = DX.Class.inherit({
setup: function(parameters) {
var that = this;
that._renderer = parameters.renderer;
that._translator = parameters.translator;
that._owner = parameters.owner;
that._tracker = parameters.tracker;
that._className = parameters.className;
that._options = {};
that._rootElement = that._createRoot();
that._trackerElement = that._createTracker();
return that
},
dispose: function() {
var that = this;
that._renderer = that._owner = that._translator = that._tracker = that._options = that._rootElement = that._trackerElement = null;
return that
},
_setupAnimation: function() {
var that = this;
if (that._options.animation)
that._animation = {
step: function(pos) {
that._actualValue = that._animation.start + that._animation.delta * pos;
that._actualPosition = that._translator.translate(that._actualValue);
that._move()
},
duration: that._options.animation.duration > 0 ? _Number(that._options.animation.duration) : 0,
easing: that._options.animation.easing
}
},
_runAnimation: function(value) {
var that = this,
animation = that._animation;
animation.start = that._actualValue;
animation.delta = value - that._actualValue;
that._rootElement.animate({_: 0}, {
step: animation.step,
duration: animation.duration,
easing: animation.easing
})
},
_createRoot: function() {
return this._renderer.createGroup({'class': this._className})
},
_createTracker: function() {
return this._renderer.createArea()
},
_getTrackerSettings: function(){},
clean: function() {
var that = this;
that._animation && that._rootElement.stopAnimation();
that._rootElement.detach();
that._rootElement.clear();
that._clear();
that._tracker.detach(that._trackerElement);
that._options = that.enabled = that._animation = null;
return that
},
render: function(options) {
var that = this;
that.type = options.type;
that._options = options;
that._actualValue = that._currentValue = that._translator.adjust(that._options.currentValue);
that.enabled = that._isEnabled();
if (that.enabled) {
that._setupAnimation();
that._rootElement.applySettings({fill: that._options.color}).append(that._owner);
that._tracker.attach(that._trackerElement, that, that._trackerInfo)
}
return that
},
resize: function(layout) {
var that = this;
that._rootElement.clear();
that._clear();
that.visible = that._isVisible(layout);
if (that.visible) {
_extend(that._options, layout);
that._actualPosition = that._translator.translate(that._actualValue);
that._render();
that._trackerElement.applySettings(that._getTrackerSettings());
that._move()
}
return that
},
value: function(arg, _noAnimation) {
var that = this;
if (arg !== undefined) {
var val = that._translator.adjust(arg);
if (that._currentValue !== val && _isFinite(val)) {
that._currentValue = val;
if (that.visible)
if (that._animation && !_noAnimation)
that._runAnimation(val);
else {
that._actualValue = val;
that._actualPosition = that._translator.translate(val);
that._move()
}
}
return that
}
return that._currentValue
},
_isEnabled: null,
_isVisible: null,
_render: null,
_clear: null,
_move: null
})
})(DevExpress, jQuery);
/*! Module viz-gauges, file baseMarker.js */
(function(DX, undefined) {
var TextCloud = DX.viz.core.TextCloud;
var formatValue = DX.viz.gauges.__internals.formatValue,
getSampleText = DX.viz.gauges.__internals.getSampleText;
DX.viz.gauges.__internals.BaseTextCloudMarker = DX.viz.gauges.__internals.BaseIndicator.inherit({
_move: function() {
var that = this,
bbox,
info = new TextCloud,
textCloudOptions = that._getTextCloudOptions();
that._text.applySettings({text: formatValue(that._actualValue, that._options.text)});
bbox = that._text.getBBox();
info.setup({
x: textCloudOptions.x,
y: textCloudOptions.y,
textWidth: bbox.width,
textHeight: bbox.height,
horMargin: that._options.horizontalOffset,
verMargin: that._options.verticalOffset,
tailLength: that._options.arrowLength,
type: textCloudOptions.type
});
that._text.applySettings({
x: info.cx(),
y: info.cy() + that._textVerticalOffset
});
that._cloud.applySettings({points: info.points()});
that._trackerElement && that._trackerElement.applySettings({points: info.points()})
},
_measureText: function() {
var that = this,
root,
text,
bbox;
if (!that._textVerticalOffset) {
root = that._createRoot().append(that._owner);
text = that._renderer.createText(getSampleText(that._translator, that._options.text), 0, 0, {
align: 'center',
font: that._options.text.font
}).append(root);
bbox = text.getBBox();
root.remove();
that._textVerticalOffset = -bbox.y - bbox.height / 2;
that._textWidth = bbox.width;
that._textHeight = bbox.height;
that._textFullWidth = that._textWidth + 2 * that._options.horizontalOffset;
that._textFullHeight = that._textHeight + 2 * that._options.verticalOffset
}
},
_render: function() {
var that = this;
that._measureText();
that._cloud = that._cloud || that._renderer.createArea().append(that._rootElement);
that._text = that._text || that._renderer.createText().append(that._rootElement);
that._text.applySettings({
align: 'center',
font: that._options.text.font
})
},
_clear: function() {
delete this._cloud;
delete this._text
},
getTooltipParameters: function() {
var position = this._getTextCloudOptions();
return {
x: position.x,
y: position.y,
value: this._currentValue,
color: this._options.color
}
}
})
})(DevExpress);
/*! Module viz-gauges, file baseRangeBar.js */
(function(DX, $, undefined) {
var $extend = $.extend;
var formatValue = DX.viz.gauges.__internals.formatValue,
getSampleText = DX.viz.gauges.__internals.getSampleText;
DX.viz.gauges.__internals.BaseRangeBar = DX.viz.gauges.__internals.BaseIndicator.inherit({
_measureText: function() {
var that = this,
root,
text,
bbox;
that._hasText = that._isTextVisible();
if (that._hasText && !that._textVerticalOffset) {
root = that._createRoot().append(that._owner);
text = that._renderer.createText(getSampleText(that._translator, that._options.text), 0, 0, {
'class': 'dxg-text',
align: 'center',
font: that._options.text.font
}).append(root);
bbox = text.getBBox();
root.remove();
that._textVerticalOffset = -bbox.y - bbox.height / 2;
that._textWidth = bbox.width;
that._textHeight = bbox.height
}
},
_move: function() {
var that = this;
that._updateBarItemsPositions();
if (that._hasText) {
that._text.applySettings({text: formatValue(that._actualValue, that._options.text)});
that._updateTextPosition();
that._updateLinePosition()
}
},
_updateBarItems: function() {
var that = this,
options = that._options,
backgroundColor,
spaceColor;
that._setBarSides();
that._startPosition = that._translator.translate(that._translator.getDomainStart());
that._endPosition = that._translator.translate(that._translator.getDomainEnd());
that._basePosition = that._translator.translate(options.baseValue);
that._space = that._getSpace();
backgroundColor = options.backgroundColor || 'none';
if (backgroundColor !== 'none' && that._space > 0)
spaceColor = options.containerBackgroundColor || 'none';
else {
that._space = 0;
spaceColor = 'none'
}
that._backItem1.applySettings({fill: backgroundColor});
that._backItem2.applySettings({fill: backgroundColor});
that._spaceItem1.applySettings({fill: spaceColor});
that._spaceItem2.applySettings({fill: spaceColor})
},
_getSpace: function() {
return 0
},
_updateTextItems: function() {
var that = this;
if (that._hasText) {
that._line = that._line || that._renderer.createPath([], {'class': 'dxg-main-bar'}).append(that._rootElement);
that._text = that._text || that._renderer.createText('', 0, 0, {'class': 'dxg-text'}).append(that._rootElement);
that._text.applySettings({
align: that._getTextAlign(),
font: that._getFontOptions()
});
that._setTextItemsSides()
}
else {
if (that._line) {
that._line.remove();
delete that._line
}
if (that._text) {
that._text.remove();
delete that._text
}
}
},
_isTextVisible: function() {
return false
},
_getTextAlign: function() {
return 'center'
},
_getFontOptions: function() {
var options = this._options,
font = options.text.font;
if (!font || !font.color)
font = $extend({}, font, {color: options.color});
return font
},
_updateBarItemsPositions: function() {
var that = this,
positions = that._getPositions();
that._backItem1.applySettings(that._buildItemSettings(positions.start, positions.back1));
that._backItem2.applySettings(that._buildItemSettings(positions.back2, positions.end));
that._spaceItem1.applySettings(that._buildItemSettings(positions.back1, positions.main1));
that._spaceItem2.applySettings(that._buildItemSettings(positions.main2, positions.back2));
that._mainItem.applySettings(that._buildItemSettings(positions.main1, positions.main2));
that._trackerElement && that._trackerElement.applySettings(that._buildItemSettings(positions.main1, positions.main2))
},
_render: function() {
var that = this;
that._measureText();
if (!that._backItem1) {
that._backItem1 = that._createBarItem();
that._backItem1.applySettings({'class': 'dxg-back-bar'})
}
if (!that._backItem2) {
that._backItem2 = that._createBarItem();
that._backItem2.applySettings({'class': 'dxg-back-bar'})
}
if (!that._spaceItem1) {
that._spaceItem1 = that._createBarItem();
that._spaceItem1.applySettings({'class': 'dxg-space-bar'})
}
if (!that._spaceItem2) {
that._spaceItem2 = that._createBarItem();
that._spaceItem2.applySettings({'class': 'dxg-space-bar'})
}
if (!that._mainItem) {
that._mainItem = that._createBarItem();
that._mainItem.applySettings({'class': 'dxg-main-bar'})
}
that._updateBarItems();
that._updateTextItems()
},
_clear: function() {
var that = this;
delete that._backItem1;
delete that._backItem2;
delete that._spaceItem1;
delete that._spaceItem2;
delete that._mainItem;
delete that._hasText;
delete that._line;
delete that._text
},
getTooltipParameters: function() {
var position = this._getTooltipPosition();
return {
x: position.x,
y: position.y,
value: this._currentValue,
color: this._options.color,
offset: 0
}
}
})
})(DevExpress, jQuery);
/*! Module viz-gauges, file circularNeedle.js */
(function(DX, undefined) {
var circularNeedles = DX.viz.gauges.__internals.circularNeedles;
var _Number = Number;
circularNeedles.SimpleIndicator = DX.viz.gauges.__internals.BaseIndicator.inherit({
_move: function() {
var that = this,
options = that._options,
angle = DX.utils.convertAngleToRendererSpace(that._actualPosition);
that._rootElement.rotate(angle, options.x, options.y);
that._trackerElement && that._trackerElement.rotate(angle, options.x, options.y)
},
_isEnabled: function() {
return this._options.width > 0
},
_isVisible: function(layout) {
return layout.radius - _Number(this._options.indentFromCenter) > 0
},
_getTrackerSettings: function() {
var options = this._options,
x = options.x,
y = options.y - (options.radius + _Number(options.indentFromCenter)) / 2,
width = options.width / 2,
length = (options.radius - _Number(options.indentFromCenter)) / 2;
width > 10 || (width = 10);
length > 10 || (length = 10);
return {points: [x - width, y - length, x - width, y + length, x + width, y + length, x + width, y - length]}
},
_renderSpindle: function() {
var that = this,
options = that._options,
gapSize;
if (options.spindleSize > 0) {
gapSize = _Number(options.spindleGapSize) || 0;
if (gapSize > 0)
gapSize = gapSize <= options.spindleSize ? gapSize : _Number(options.spindleSize);
that._spindleOuter = that._spindleOuter || that._renderer.createCircle().append(that._rootElement);
that._spindleInner = that._spindleInner || that._renderer.createCircle().append(that._rootElement);
that._spindleOuter.applySettings({
'class': 'dxg-spindle-border',
cx: options.x,
cy: options.y,
r: options.spindleSize / 2
});
that._spindleInner.applySettings({
'class': 'dxg-spindle-hole',
cx: options.x,
cy: options.y,
r: gapSize / 2,
fill: options.containerBackgroundColor
})
}
},
_render: function() {
var that = this;
that._renderPointer();
that._renderSpindle()
},
_clearSpindle: function() {
delete this._spindleOuter;
delete this._spindleInner
},
_clearPointer: function() {
delete this._element
},
_clear: function() {
this._clearPointer();
this._clearSpindle()
},
measure: function(layout) {
var result = {max: layout.radius};
if (this._options.indentFromCenter < 0)
result.inverseHorizontalOffset = result.inverseVerticalOffset = -_Number(this._options.indentFromCenter);
return result
},
getTooltipParameters: function() {
var options = this._options,
cossin = DX.utils.getCosAndSin(this._actualPosition),
r = (options.radius + _Number(options.indentFromCenter)) / 2;
return {
x: options.x + cossin.cos * r,
y: options.y - cossin.sin * r,
value: this._currentValue,
color: options.color,
offset: options.width / 2
}
}
});
circularNeedles.RectangleNeedle = circularNeedles.SimpleIndicator.inherit({_renderPointer: function() {
var that = this,
options = that._options,
y2 = options.y - options.radius,
y1 = options.y - _Number(options.indentFromCenter),
x1 = options.x - options.width / 2,
x2 = x1 + _Number(options.width);
that._element = that._element || that._renderer.createArea().append(that._rootElement);
that._element.applySettings({points: [x1, y1, x1, y2, x2, y2, x2, y1]})
}});
circularNeedles.TriangleNeedle = circularNeedles.SimpleIndicator.inherit({_renderPointer: function() {
var that = this,
options = that._options,
y2 = options.y - options.radius,
y1 = options.y - _Number(options.indentFromCenter),
x1 = options.x - options.width / 2,
x2 = options.x + options.width / 2;
that._element = that._element || that._renderer.createArea().append(that._rootElement);
that._element.applySettings({points: [x1, y1, options.x, y2, x2, y1]})
}});
circularNeedles.TwoColorRectangleNeedle = circularNeedles.SimpleIndicator.inherit({
_renderPointer: function() {
var that = this,
options = that._options,
x1 = options.x - options.width / 2,
x2 = options.x + options.width / 2,
y4 = options.y - options.radius,
y1 = options.y - _Number(options.indentFromCenter),
fraction = _Number(options.secondFraction) || 0,
y2,
y3;
if (fraction >= 1)
y2 = y3 = y1;
else if (fraction <= 0)
y2 = y3 = y2;
else {
y3 = y4 + (y1 - y4) * fraction;
y2 = y3 + options.space
}
that._firstElement = that._firstElement || that._renderer.createArea().append(that._rootElement);
that._spaceElement = that._spaceElement || that._renderer.createArea().append(that._rootElement);
that._secondElement = that._secondElement || that._renderer.createArea().append(that._rootElement);
that._firstElement.applySettings({points: [x1, y1, x1, y2, x2, y2, x2, y1]});
that._spaceElement.applySettings({
points: [x1, y2, x1, y3, x2, y3, x2, y2],
'class': 'dxg-hole',
fill: options.containerBackgroundColor
});
that._secondElement.applySettings({
points: [x1, y3, x1, y4, x2, y4, x2, y3],
'class': 'dxg-part',
fill: options.secondColor
})
},
_clearPointer: function() {
delete this._firstElement;
delete this._secondElement;
delete this._spaceElement
}
})
})(DevExpress);
/*! Module viz-gauges, file linearNeedle.js */
(function(DX, undefined) {
var linearNeedles = DX.viz.gauges.__internals.linearNeedles;
var _Number = Number;
linearNeedles.SimpleIndicator = DX.viz.gauges.__internals.BaseIndicator.inherit({
_move: function() {
var that = this,
delta = that._actualPosition - that._zeroPosition;
that._rootElement.move(that.vertical ? 0 : delta, that.vertical ? delta : 0);
that._trackerElement && that._trackerElement.move(that.vertical ? 0 : delta, that.vertical ? delta : 0)
},
_isEnabled: function() {
this.vertical = this._options.vertical;
return this._options.length > 0 && this._options.width > 0
},
_isVisible: function(layout) {
return true
},
_getTrackerSettings: function() {
var options = this._options,
x1,
x2,
y1,
y2,
width = options.width / 2,
length = options.length / 2,
p = this._zeroPosition;
width > 10 || (width = 10);
length > 10 || (length = 10);
if (this.vertical) {
x1 = options.x - length;
x2 = options.x + length;
y1 = p + width;
y2 = p - width
}
else {
x1 = p - width;
x2 = p + width;
y1 = options.y + length;
y2 = options.y - length
}
return {points: [x1, y1, x1, y2, x2, y2, x2, y1]}
},
_render: function() {
var that = this;
that._zeroPosition = that._translator.getCodomainStart()
},
_clear: function() {
delete this._element
},
measure: function(layout) {
var p = this.vertical ? layout.x : layout.y;
return {
min: p - this._options.length / 2,
max: p + this._options.length / 2
}
},
getTooltipParameters: function() {
var that = this,
options = that._options,
p = that._actualPosition,
parameters = {
x: p,
y: p,
value: that._currentValue,
color: options.color,
offset: options.width / 2
};
that.vertical ? parameters.x = options.x : parameters.y = options.y;
return parameters
}
});
linearNeedles.RectangleNeedle = linearNeedles.SimpleIndicator.inherit({_render: function() {
var that = this,
options = that._options,
p,
x1,
x2,
y1,
y2;
that.callBase();
p = that._zeroPosition;
if (that.vertical) {
x1 = options.x - options.length / 2;
x2 = options.x + options.length / 2;
y1 = p + options.width / 2;
y2 = p - options.width / 2
}
else {
x1 = p - options.width / 2;
x2 = p + options.width / 2;
y1 = options.y + options.length / 2;
y2 = options.y - options.length / 2
}
that._element = that._element || that._renderer.createArea().append(that._rootElement);
that._element.applySettings({points: [x1, y1, x1, y2, x2, y2, x2, y1]})
}});
linearNeedles.RhombusNeedle = linearNeedles.SimpleIndicator.inherit({_render: function() {
var that = this,
options = that._options,
x,
y,
dx,
dy;
that.callBase();
if (that.vertical) {
x = options.x;
y = that._zeroPosition;
dx = options.length / 2 || 0;
dy = options.width / 2 || 0
}
else {
x = that._zeroPosition;
y = options.y;
dx = options.width / 2 || 0;
dy = options.length / 2 || 0
}
that._element = that._element || that._renderer.createArea().append(that._rootElement);
that._element.applySettings({points: [x - dx, y, x, y - dy, x + dx, y, x, y + dy]})
}});
linearNeedles.CircleNeedle = linearNeedles.SimpleIndicator.inherit({_render: function() {
var that = this,
options = that._options,
x,
y,
r;
that.callBase();
if (that.vertical) {
x = options.x;
y = that._zeroPosition
}
else {
x = that._zeroPosition;
y = options.y
}
r = options.length / 2 || 0;
that._element = that._element || that._renderer.createCircle().append(that._rootElement);
that._element.applySettings({
cx: x,
cy: y,
r: r
})
}})
})(DevExpress);
/*! Module viz-gauges, file circularMarker.js */
(function(DX, undefined) {
var circularMarkers = DX.viz.gauges.__internals.circularMarkers;
var _Number = Number;
circularMarkers.TriangleMarker = DX.viz.gauges.__internals.circularNeedles.SimpleIndicator.inherit({
_isEnabled: function() {
return this._options.length > 0 && this._options.width > 0
},
_isVisible: function(layout) {
return layout.radius > 0
},
_render: function() {
var that = this,
options = that._options,
x = options.x,
y1 = options.y - options.radius,
dx = options.width / 2 || 0,
y2 = y1 - _Number(options.length),
settings;
that._element = that._element || that._renderer.createArea().append(that._rootElement);
settings = {
points: [x, y1, x - dx, y2, x + dx, y2],
stroke: 'none',
strokeWidth: 0
};
if (options.space > 0) {
settings.strokeWidth = Math.min(options.space, options.width / 4) || 0;
settings.stroke = settings.strokeWidth > 0 ? options.containerBackgroundColor || 'none' : 'none'
}
that._element.applySettings(settings)
},
_clear: function() {
delete this._element
},
_getTrackerSettings: function() {
var options = this._options,
x = options.x,
y = options.y - options.radius - options.length / 2,
width = options.width / 2,
length = options.length / 2;
width > 10 || (width = 10);
length > 10 || (length = 10);
return {points: [x - width, y - length, x - width, y + length, x + width, y + length, x + width, y - length]}
},
measure: function(layout) {
return {
min: layout.radius,
max: layout.radius + _Number(this._options.length)
}
},
getTooltipParameters: function() {
var options = this._options,
cossin = DX.utils.getCosAndSin(this._actualPosition),
r = options.radius + options.length / 2,
parameters = this.callBase();
parameters.x = options.x + cossin.cos * r;
parameters.y = options.y - cossin.sin * r;
parameters.offset = options.length / 2;
return parameters
}
});
circularMarkers.TextCloudMarker = DX.viz.gauges.__internals.BaseTextCloudMarker.inherit({
_isEnabled: function() {
return true
},
_isVisible: function(layout) {
return layout.radius > 0
},
_getTextCloudOptions: function() {
var that = this,
cossin = DX.utils.getCosAndSin(that._actualPosition),
nangle = DX.utils.normalizeAngle(that._actualPosition);
return {
x: that._options.x + cossin.cos * that._options.radius,
y: that._options.y - cossin.sin * that._options.radius,
type: nangle > 270 ? 'left-top' : nangle > 180 ? 'top-right' : nangle > 90 ? 'right-bottom' : 'bottom-left'
}
},
measure: function(layout) {
var that = this;
that._measureText();
return {
min: layout.radius,
max: layout.radius,
horizontalOffset: that._textFullWidth + (_Number(that._options.arrowLength) || 0),
verticalOffset: that._textFullHeight + (_Number(that._options.arrowLength) || 0)
}
}
})
})(DevExpress);
/*! Module viz-gauges, file linearMarker.js */
(function(DX, undefined) {
var linearMarkers = DX.viz.gauges.__internals.linearMarkers;
var _Number = Number,
_String = String;
linearMarkers.TriangleMarker = DX.viz.gauges.__internals.linearNeedles.SimpleIndicator.inherit({
_isEnabled: function() {
var that = this;
that.vertical = that._options.vertical;
that._inverted = that.vertical ? _String(that._options.horizontalOrientation).toLowerCase() === 'right' : _String(that._options.verticalOrientation).toLowerCase() === 'bottom';
return that._options.length > 0 && that._options.width > 0
},
_isVisible: function(layout) {
return true
},
_render: function() {
var that = this,
options = that._options,
x1,
x2,
y1,
y2,
settings = {
stroke: 'none',
strokeWidth: 0
};
that.callBase();
if (that.vertical) {
x1 = options.x;
y1 = that._zeroPosition;
x2 = x1 + _Number(that._inverted ? options.length : -options.length);
settings.points = [x1, y1, x2, y1 - options.width / 2, x2, y1 + options.width / 2]
}
else {
y1 = options.y;
x1 = that._zeroPosition;
y2 = y1 + _Number(that._inverted ? options.length : -options.length);
settings.points = [x1, y1, x1 - options.width / 2, y2, x1 + options.width / 2, y2]
}
if (options.space > 0) {
settings.strokeWidth = Math.min(options.space, options.width / 4) || 0;
settings.stroke = settings.strokeWidth > 0 ? options.containerBackgroundColor || 'none' : 'none'
}
that._element = that._element || that._renderer.createArea().append(that._rootElement);
that._element.applySettings(settings)
},
_getTrackerSettings: function() {
var that = this,
options = that._options,
width = options.width / 2,
length = _Number(options.length),
x1,
x2,
y1,
y2,
result;
width > 10 || (width = 10);
length > 20 || (length = 20);
if (that.vertical) {
x1 = x2 = options.x;
x2 = x1 + (that._inverted ? length : -length);
y1 = that._zeroPosition + width;
y2 = that._zeroPosition - width;
result = [x1, y1, x2, y1, x2, y2, x1, y2]
}
else {
y1 = options.y;
y2 = y1 + (that._inverted ? length : -length);
x1 = that._zeroPosition - width;
x2 = that._zeroPosition + width;
result = [x1, y1, x1, y2, x2, y2, x2, y1]
}
return {points: result}
},
measure: function(layout) {
var that = this,
length = _Number(that._options.length),
minbound,
maxbound;
if (that.vertical) {
minbound = maxbound = layout.x;
if (that._inverted)
maxbound = minbound + length;
else
minbound = maxbound - length
}
else {
minbound = maxbound = layout.y;
if (that._inverted)
maxbound = minbound + length;
else
minbound = maxbound - length
}
return {
min: minbound,
max: maxbound,
indent: that._options.width / 2
}
},
getTooltipParameters: function() {
var that = this,
options = that._options,
s = (that._inverted ? options.length : -options.length) / 2,
parameters = that.callBase();
that.vertical ? parameters.x += s : parameters.y += s;
parameters.offset = options.length / 2;
return parameters
}
});
linearMarkers.TextCloudMarker = DX.viz.gauges.__internals.BaseTextCloudMarker.inherit({
_isEnabled: function() {
var that = this;
that.vertical = that._options.vertical;
that._inverted = that.vertical ? _String(that._options.horizontalOrientation).toLowerCase() === 'right' : _String(that._options.verticalOrientation).toLowerCase() === 'bottom';
return true
},
_isVisible: function(layout) {
return true
},
_getTextCloudOptions: function() {
var that = this,
x = that._actualPosition,
y = that._actualPosition,
type;
if (that.vertical) {
x = that._options.x;
type = that._inverted ? 'top-left' : 'top-right'
}
else {
y = that._options.y;
type = that._inverted ? 'right-top' : 'right-bottom'
}
return {
x: x,
y: y,
type: type
}
},
measure: function(layout) {
var that = this,
minbound,
maxbound,
arrowLength = _Number(that._options.arrowLength) || 0,
indent;
that._measureText();
if (that.vertical) {
indent = that._textFullHeight;
if (that._inverted) {
minbound = layout.x;
maxbound = layout.x + arrowLength + that._textFullWidth
}
else {
minbound = layout.x - arrowLength - that._textFullWidth;
maxbound = layout.x
}
}
else {
indent = that._textFullWidth;
if (that._inverted) {
minbound = layout.y;
maxbound = layout.y + arrowLength + that._textFullHeight
}
else {
minbound = layout.y - arrowLength - that._textFullHeight;
maxbound = layout.y
}
}
return {
min: minbound,
max: maxbound,
indent: indent
}
}
})
})(DevExpress);
/*! Module viz-gauges, file circularRangeBar.js */
(function(DX, undefined) {
var _Number = Number,
getCosAndSin = DX.utils.getCosAndSin,
convertAngleToRendererSpace = DX.utils.convertAngleToRendererSpace,
max = Math.max,
min = Math.min;
DX.viz.gauges.__internals.CircularRangeBar = DX.viz.gauges.__internals.BaseRangeBar.inherit({
_isEnabled: function() {
return this._options.size > 0
},
_isVisible: function(layout) {
return layout.radius - _Number(this._options.size) > 0
},
_createBarItem: function() {
return this._renderer.createArc().append(this._rootElement)
},
_createTracker: function() {
return this._renderer.createArc()
},
_setBarSides: function() {
var that = this;
that._maxSide = that._options.radius;
that._minSide = that._maxSide - _Number(that._options.size)
},
_getSpace: function() {
var options = this._options;
return options.space > 0 ? options.space * 180 / options.radius / Math.PI : 0
},
_isTextVisible: function() {
var options = this._options.text || {};
return options.indent > 0
},
_setTextItemsSides: function() {
var that = this,
options = that._options;
that._lineFrom = options.y - options.radius;
that._lineTo = that._lineFrom - _Number(options.text.indent);
that._textRadius = options.radius + _Number(options.text.indent)
},
_getPositions: function() {
var that = this,
basePosition = that._basePosition,
actualPosition = that._actualPosition,
mainPosition1,
mainPosition2;
if (basePosition >= actualPosition) {
mainPosition1 = basePosition;
mainPosition2 = actualPosition
}
else {
mainPosition1 = actualPosition;
mainPosition2 = basePosition
}
return {
start: that._startPosition,
end: that._endPosition,
main1: mainPosition1,
main2: mainPosition2,
back1: min(mainPosition1 + that._space, that._startPosition),
back2: max(mainPosition2 - that._space, that._endPosition)
}
},
_buildItemSettings: function(from, to) {
var that = this;
return {
x: that._options.x,
y: that._options.y,
innerRadius: that._minSide,
outerRadius: that._maxSide,
startAngle: to,
endAngle: from
}
},
_updateTextPosition: function() {
var that = this,
cossin = getCosAndSin(that._actualPosition),
x = that._options.x + that._textRadius * cossin.cos,
y = that._options.y - that._textRadius * cossin.sin;
x += cossin.cos * that._textWidth * 0.6;
y -= cossin.sin * that._textHeight * 0.6;
that._text.applySettings({
x: x,
y: y + that._textVerticalOffset
})
},
_updateLinePosition: function() {
var that = this,
x = that._options.x,
x1,
x2;
if (that._basePosition > that._actualPosition) {
x1 = x - 2;
x2 = x
}
else if (that._basePosition < that._actualPosition) {
x1 = x;
x2 = x + 2
}
else {
x1 = x - 1;
x2 = x + 1
}
that._line.applySettings({points: [x1, that._lineFrom, x1, that._lineTo, x2, that._lineTo, x2, that._lineFrom]});
that._line.rotate(convertAngleToRendererSpace(that._actualPosition), x, that._options.y)
},
_getTooltipPosition: function() {
var that = this,
cossin = getCosAndSin((that._basePosition + that._actualPosition) / 2),
r = (that._minSide + that._maxSide) / 2;
return {
x: that._options.x + cossin.cos * r,
y: that._options.y - cossin.sin * r
}
},
measure: function(layout) {
var that = this,
result = {
min: layout.radius - _Number(that._options.size),
max: layout.radius
};
that._measureText();
if (that._hasText) {
result.max += _Number(that._options.text.indent);
result.horizontalOffset = that._textWidth;
result.verticalOffset = that._textHeight
}
return result
}
})
})(DevExpress);
/*! Module viz-gauges, file linearRangeBar.js */
(function(DX, undefined) {
var _Number = Number,
_String = String;
DX.viz.gauges.__internals.LinearRangeBar = DX.viz.gauges.__internals.BaseRangeBar.inherit({
_isEnabled: function() {
var that = this;
that.vertical = that._options.vertical;
that._inverted = that.vertical ? _String(that._options.horizontalOrientation).toLowerCase() === 'right' : _String(that._options.verticalOrientation).toLowerCase() === 'bottom';
return that._options.size > 0
},
_isVisible: function(layout) {
return true
},
_createBarItem: function() {
return this._renderer.createArea().append(this._rootElement)
},
_createTracker: function() {
return this._renderer.createArea()
},
_setBarSides: function() {
var that = this,
options = that._options,
size = _Number(options.size),
minSide,
maxSide;
if (that.vertical)
if (that._inverted) {
minSide = options.x;
maxSide = options.x + size
}
else {
minSide = options.x - size;
maxSide = options.x
}
else if (that._inverted) {
minSide = options.y;
maxSide = options.y + size
}
else {
minSide = options.y - size;
maxSide = options.y
}
that._minSide = minSide;
that._maxSide = maxSide;
that._minBound = minSide;
that._maxBound = maxSide
},
_getSpace: function() {
var options = this._options;
return options.space > 0 ? _Number(options.space) : 0
},
_isTextVisible: function() {
var textOptions = this._options.text || {};
return textOptions.indent > 0 || textOptions.indent < 0
},
_getTextAlign: function() {
return this.vertical ? this._options.text.indent > 0 ? 'left' : 'right' : 'center'
},
_setTextItemsSides: function() {
var that = this,
indent = _Number(that._options.text.indent);
if (indent > 0) {
that._lineStart = that._maxSide;
that._lineEnd = that._maxSide + indent;
that._textPosition = that._lineEnd + (that.vertical ? 2 : that._textHeight / 2);
that._maxBound = that._textPosition + (that.vertical ? that._textWidth : that._textHeight / 2)
}
else if (indent < 0) {
that._lineStart = that._minSide;
that._lineEnd = that._minSide + indent;
that._textPosition = that._lineEnd - (that.vertical ? 2 : that._textHeight / 2);
that._minBound = that._textPosition - (that.vertical ? that._textWidth : that._textHeight / 2)
}
},
_getPositions: function() {
var that = this,
options = that._options,
startPosition = that._startPosition,
endPosition = that._endPosition,
space = that._space,
basePosition = that._basePosition,
actualPosition = that._actualPosition,
mainPosition1,
mainPosition2,
backPosition1,
backPosition2;
if (startPosition < endPosition) {
if (basePosition < actualPosition) {
mainPosition1 = basePosition;
mainPosition2 = actualPosition
}
else {
mainPosition1 = actualPosition;
mainPosition2 = basePosition
}
backPosition1 = mainPosition1 - space;
backPosition2 = mainPosition2 + space
}
else {
if (basePosition > actualPosition) {
mainPosition1 = basePosition;
mainPosition2 = actualPosition
}
else {
mainPosition1 = actualPosition;
mainPosition2 = basePosition
}
backPosition1 = mainPosition1 + space;
backPosition2 = mainPosition2 - space
}
return {
start: startPosition,
end: endPosition,
main1: mainPosition1,
main2: mainPosition2,
back1: backPosition1,
back2: backPosition2
}
},
_buildItemSettings: function(from, to) {
var that = this,
side1 = that._minSide,
side2 = that._maxSide;
var points = that.vertical ? [side1, from, side1, to, side2, to, side2, from] : [from, side1, from, side2, to, side2, to, side1];
return {points: points}
},
_updateTextPosition: function() {
var that = this;
that._text.applySettings(that.vertical ? {
x: that._textPosition,
y: that._actualPosition + that._textVerticalOffset
} : {
x: that._actualPosition,
y: that._textPosition + that._textVerticalOffset
})
},
_updateLinePosition: function() {
var that = this,
actualPosition = that._actualPosition,
side1,
side2,
points;
if (that.vertical) {
if (that._basePosition >= actualPosition) {
side1 = actualPosition;
side2 = actualPosition + 2
}
else {
side1 = actualPosition - 2;
side2 = actualPosition
}
points = [that._lineStart, side1, that._lineStart, side2, that._lineEnd, side2, that._lineEnd, side1]
}
else {
if (that._basePosition <= actualPosition) {
side1 = actualPosition - 2;
side2 = actualPosition
}
else {
side1 = actualPosition;
side2 = actualPosition + 2
}
points = [side1, that._lineStart, side1, that._lineEnd, side2, that._lineEnd, side2, that._lineStart]
}
that._line.applySettings({points: points})
},
_getTooltipPosition: function() {
var that = this,
crossCenter = (that._minSide + that._maxSide) / 2,
alongCenter = (that._basePosition + that._actualPosition) / 2,
position = {};
if (that.vertical)
position = {
x: crossCenter,
y: alongCenter
};
else
position = {
x: alongCenter,
y: crossCenter
};
return position
},
measure: function(layout) {
var that = this,
size = _Number(that._options.size),
textIndent = _Number(that._options.text.indent),
minbound,
maxbound,
indent;
that._measureText();
if (that.vertical) {
minbound = maxbound = layout.x;
if (that._inverted)
maxbound = maxbound + size;
else
minbound = minbound - size;
if (that._hasText) {
indent = that._textHeight / 2;
if (textIndent > 0)
maxbound += textIndent + that._textWidth;
if (textIndent < 0)
minbound += textIndent - that._textWidth
}
}
else {
minbound = maxbound = layout.y;
if (that._inverted)
maxbound = maxbound + size;
else
minbound = minbound - size;
if (that._hasText) {
indent = that._textWidth / 2;
if (textIndent > 0)
maxbound += textIndent + that._textHeight;
if (textIndent < 0)
minbound += textIndent - that._textHeight
}
}
return {
min: minbound,
max: maxbound,
indent: indent
}
}
})
})(DevExpress);
/*! Module viz-gauges, file rangeContainer.js */
(function(DX, $, undefined) {
var _Number = Number,
_String = String,
_max = Math.max,
_abs = Math.abs,
_isString = DX.utils.isString,
_isArray = DX.utils.isArray,
_isFinite = isFinite,
_each = $.each,
_map = $.map;
var _Palette = DX.viz.core.Palette;
DX.viz.gauges.__internals.BaseRangeContainer = DX.Class.inherit({
ctor: function(parameters) {
var that = this;
that._renderer = parameters.renderer;
that._container = parameters.container;
that._translator = parameters.translator;
that._root = that._renderer.createGroup({'class': 'dxg-range-container'})
},
dispose: function() {
var that = this;
that._renderer = that._container = that._translator = that._root = null
},
clean: function() {
this._root.detach().clear();
this._options = this.enabled = null;
return this
},
_getRanges: function() {
var that = this,
options = that._options,
translator = that._translator,
totalStart = translator.getDomain()[0],
totalEnd = translator.getDomain()[1],
totalDelta = totalEnd - totalStart,
isNotEmptySegment = totalDelta >= 0 ? isNotEmptySegmentAsc : isNotEmptySegmentDes,
subtractSegment = totalDelta >= 0 ? subtractSegmentAsc : subtractSegmentDes,
list = [],
ranges = [],
backgroundRanges = [{
start: totalStart,
end: totalEnd
}],
threshold = _abs(totalDelta) / 1E4,
palette = new _Palette(options.palette, {
type: 'indicatingSet',
theme: options.themeName
}),
backgroundColor = _isString(options.backgroundColor) ? options.backgroundColor : 'none',
width = options.width || {},
startWidth = _Number(width > 0 ? width : width.start),
endWidth = _Number(width > 0 ? width : width.end),
deltaWidth = endWidth - startWidth;
if (options.ranges !== undefined && !_isArray(options.ranges))
return null;
if (!(startWidth >= 0 && endWidth >= 0 && startWidth + endWidth > 0))
return null;
list = _map(_isArray(options.ranges) ? options.ranges : [], function(rangeOptions, i) {
rangeOptions = rangeOptions || {};
var start = translator.adjust(rangeOptions.startValue),
end = translator.adjust(rangeOptions.endValue);
return _isFinite(start) && _isFinite(end) && isNotEmptySegment(start, end, threshold) ? {
start: start,
end: end,
color: rangeOptions.color,
classIndex: i
} : null
});
_each(list, function(i, item) {
var paletteColor = palette.getNextColor();
item.color = _isString(item.color) && item.color || paletteColor || 'none';
item.className = 'dxg-range dxg-range-' + item.classIndex;
delete item.classIndex
});
_each(list, function(_, item) {
var i,
ii,
sub,
subs,
range,
newRanges = [],
newBackgroundRanges = [];
for (i = 0, ii = ranges.length; i < ii; ++i) {
range = ranges[i];
subs = subtractSegment(range.start, range.end, item.start, item.end);
(sub = subs[0]) && (sub.color = range.color) && (sub.className = range.className) && newRanges.push(sub);
(sub = subs[1]) && (sub.color = range.color) && (sub.className = range.className) && newRanges.push(sub)
}
newRanges.push(item);
ranges = newRanges;
for (i = 0, ii = backgroundRanges.length; i < ii; ++i) {
range = backgroundRanges[i];
subs = subtractSegment(range.start, range.end, item.start, item.end);
(sub = subs[0]) && newBackgroundRanges.push(sub);
(sub = subs[1]) && newBackgroundRanges.push(sub)
}
backgroundRanges = newBackgroundRanges
});
_each(backgroundRanges, function(_, range) {
range.color = backgroundColor;
range.className = 'dxg-range dxg-background-range';
ranges.push(range)
});
_each(ranges, function(_, range) {
range.startWidth = (range.start - totalStart) / totalDelta * deltaWidth + startWidth;
range.endWidth = (range.end - totalStart) / totalDelta * deltaWidth + startWidth
});
return ranges
},
render: function(options) {
var that = this;
that._options = options;
that._processOptions();
that._ranges = that._getRanges();
if (that._ranges) {
that.enabled = true;
that._root.append(that._container)
}
return that
},
resize: function(layout) {
var that = this;
that._root.clear();
if (that._isVisible(layout))
_each(that._ranges, function(_, range) {
that._createRange(range, layout).applySettings({
fill: range.color,
'class': range.className
}).append(that._root)
});
return that
},
_processOptions: null,
_isVisible: null,
_createRange: null
});
function subtractSegmentAsc(segmentStart, segmentEnd, otherStart, otherEnd) {
var result;
if (otherStart > segmentStart && otherEnd < segmentEnd)
result = [{
start: segmentStart,
end: otherStart
}, {
start: otherEnd,
end: segmentEnd
}];
else if (otherStart >= segmentEnd || otherEnd <= segmentStart)
result = [{
start: segmentStart,
end: segmentEnd
}];
else if (otherStart <= segmentStart && otherEnd >= segmentEnd)
result = [];
else if (otherStart > segmentStart)
result = [{
start: segmentStart,
end: otherStart
}];
else if (otherEnd < segmentEnd)
result = [{
start: otherEnd,
end: segmentEnd
}];
return result
}
function subtractSegmentDes(segmentStart, segmentEnd, otherStart, otherEnd) {
var result;
if (otherStart < segmentStart && otherEnd > segmentEnd)
result = [{
start: segmentStart,
end: otherStart
}, {
start: otherEnd,
end: segmentEnd
}];
else if (otherStart <= segmentEnd || otherEnd >= segmentStart)
result = [{
start: segmentStart,
end: segmentEnd
}];
else if (otherStart >= segmentStart && otherEnd <= segmentEnd)
result = [];
else if (otherStart < segmentStart)
result = [{
start: segmentStart,
end: otherStart
}];
else if (otherEnd > segmentEnd)
result = [{
start: otherEnd,
end: segmentEnd
}];
return result
}
function isNotEmptySegmentAsc(start, end, threshold) {
return end - start >= threshold
}
function isNotEmptySegmentDes(start, end, threshold) {
return start - end >= threshold
}
DX.viz.gauges.__internals.CircularRangeContainer = DX.viz.gauges.__internals.BaseRangeContainer.inherit({
_processOptions: function() {
var that = this;
that._inner = that._outer = 0;
switch (_String(that._options.orientation).toLowerCase()) {
case'inside':
that._inner = 1;
break;
case'center':
that._inner = that._outer = 0.5;
break;
default:
that._outer = 1;
break
}
},
_isVisible: function(layout) {
var width = this._options.width;
width = _Number(width) || _max(_Number(width.start), _Number(width.end));
return layout.radius - this._inner * width > 0
},
_createRange: function(range, layout) {
var that = this,
width = (range.startWidth + range.endWidth) / 2;
return that._renderer.createArc(layout.x, layout.y, layout.radius + that._outer * width, layout.radius - that._inner * width, that._translator.translate(range.end), that._translator.translate(range.start))
},
measure: function(layout) {
var width = this._options.width;
width = _Number(width) || _max(_Number(width.start), _Number(width.end));
return {
min: layout.radius - this._inner * width,
max: layout.radius + this._outer * width
}
}
});
DX.viz.gauges.__internals.LinearRangeContainer = DX.viz.gauges.__internals.BaseRangeContainer.inherit({
_processOptions: function() {
var that = this;
that.vertical = that._options.vertical;
that._inner = that._outer = 0;
if (that.vertical)
switch (_String(that._options.horizontalOrientation).toLowerCase()) {
case'left':
that._inner = 1;
break;
case'center':
that._inner = that._outer = 0.5;
break;
default:
that._outer = 1;
break
}
else
switch (_String(that._options.verticalOrientation).toLowerCase()) {
case'top':
that._inner = 1;
break;
case'middle':
that._inner = that._outer = 0.5;
break;
default:
that._outer = 1;
break
}
},
_isVisible: function(layout) {
return true
},
_createRange: function(range, layout) {
var that = this,
inner = that._inner,
outer = that._outer,
startPosition = that._translator.translate(range.start),
endPosition = that._translator.translate(range.end),
points;
if (that.vertical)
points = [layout.x - range.startWidth * inner, startPosition, layout.x - range.endWidth * inner, endPosition, layout.x + range.endWidth * outer, endPosition, layout.x + range.startWidth * outer, startPosition];
else
points = [startPosition, layout.y + range.startWidth * outer, startPosition, layout.y - range.startWidth * inner, endPosition, layout.y - range.endWidth * inner, endPosition, layout.y + range.endWidth * outer];
return that._renderer.createArea(points)
},
measure: function(layout) {
var result = {};
result.min = result.max = layout[this.vertical ? 'x' : 'y'];
var width = this._options.width;
width = _Number(width) || _max(_Number(width.start), _Number(width.end));
result.min -= this._inner * width;
result.max += this._outer * width;
return result
}
})
})(DevExpress, jQuery);
/*! Module viz-gauges, file title.js */
(function(DX, $, undefined) {
var _isString = DX.utils.isString,
_max = Math.max,
_extend = $.extend;
DX.viz.gauges.__internals.Title = DX.Class.inherit({
ctor: function(parameters) {
this._renderer = parameters.renderer;
this._container = parameters.container
},
dispose: function() {
this._renderer = this._container = null;
return this
},
clean: function() {
var that = this;
if (that._root) {
that._root.detach().clear();
that._root = that._layout = null
}
return that
},
render: function(titleOptions, subtitleOptions) {
var that = this,
hasTitle = _isString(titleOptions.text) && titleOptions.text.length > 0,
hasSubtitle = _isString(subtitleOptions.text) && subtitleOptions.text.length > 0;
if (!hasTitle && !hasSubtitle)
return that;
that._root = that._renderer.createGroup({'class': 'dxg-title'}).append(that._container);
var title = hasTitle ? that._renderer.createText(titleOptions.text, 0, 0, {
align: 'center',
font: titleOptions.font
}).append(that._root) : null,
subtitle = hasSubtitle ? that._renderer.createText(subtitleOptions.text, 0, 0, {
align: 'center',
font: subtitleOptions.font
}).append(that._root) : null,
titleBox = title ? title.getBBox() : {},
subtitleBox = subtitle ? subtitle.getBBox() : {},
y = 0;
if (title) {
y += -titleBox.y;
title.applySettings({
x: 0,
y: y
})
}
if (subtitle) {
y += -subtitleBox.y;
subtitle.applySettings({
x: 0,
y: y
})
}
that._layout = _extend({
position: titleOptions.position,
width: _max(titleBox.width || 0, subtitleBox.width || 0),
height: title && subtitle ? -titleBox.y + subtitleBox.height : titleBox.height || subtitleBox.height
}, titleOptions.layout);
return that
},
getLayoutOptions: function() {
return this._layout
},
locate: function(left, top) {
this._root.applySettings({
translateX: left + this._layout.width / 2,
translateY: top
});
return this
}
})
})(DevExpress, jQuery);
/*! Module viz-gauges, file tooltip.js */
(function(DX, $, undefined) {
var _extend = $.extend;
DX.viz.gauges.__internals.Tooltip = DX.viz.core.Tooltip.inherit({
ctor: function(parameters) {
var that = this;
that._container = parameters.container;
that._tracker = parameters.tracker;
that._root = parameters.renderer.createGroup({'class': 'dxg-tooltip'});
that.callBase(null, that._root, parameters.renderer);
that._setTrackerCallbacks()
},
dispose: function() {
var that = this;
that._container = that._tracker = that._root = null;
return that._shadow ? that.callBase.apply(that, arguments) : that
},
_setTrackerCallbacks: function() {
var that = this;
function prepareCallback(target, info) {
var tooltipParameters = target.getTooltipParameters(),
formatObject = _extend({
value: tooltipParameters.value,
valueText: that.formatValue(tooltipParameters.value),
color: tooltipParameters.color
}, info);
return that.prepare(formatObject, {
x: tooltipParameters.x,
y: tooltipParameters.y,
offset: tooltipParameters.offset
})
}
function showCallback() {
return that.show()
}
function hideCallback() {
return that.hide()
}
that._tracker.setCallbacks({
'tooltip-prepare': prepareCallback,
'tooltip-show': showCallback,
'tooltip-hide': hideCallback
})
},
clean: function() {
this._root.detach();
return this
},
render: function(options, size) {
var that = this;
options.canvasWidth = size.width;
options.canvasHeight = size.height;
options.text = {'class': 'dxg-text'};
that.update(options);
that._tracker.setTooltipState(that.enabled());
that.enabled() && that._root.append(that._container);
return that
}
})
})(DevExpress, jQuery);
/*! Module viz-gauges, file layoutManager.js */
(function(DX, $, undefined) {
var _Number = Number,
_String = String,
_min = Math.min,
_max = Math.max,
_each = $.each;
function patchLayoutOptions(options) {
if (options.position) {
var position = _String(options.position).toLowerCase().split('-');
options.verticalAlignment = position[0];
options.horizontalAlignment = position[1]
}
}
DX.viz.gauges.__internals.LayoutManager = DX.Class.inherit({
setRect: function(rect) {
this._currentRect = rect.clone();
return this
},
getRect: function() {
return this._currentRect.clone()
},
beginLayout: function(rect) {
this._rootRect = rect.clone();
this._currentRect = rect.clone();
this._cache = [];
return this
},
applyLayout: function(target) {
var options = target.getLayoutOptions();
if (!options)
return this;
var currentRect = this._currentRect,
verticalOverlay = _Number(options.overlay) || 0;
patchLayoutOptions(options);
switch (_String(options.verticalAlignment).toLowerCase()) {
case'bottom':
currentRect.bottom -= _max(options.height - verticalOverlay, 0);
break;
default:
currentRect.top += _max(options.height - verticalOverlay, 0);
break
}
this._cache.push({
target: target,
options: options
});
return this
},
endLayout: function() {
var that = this,
rootRect = that._rootRect,
currentRect = that._currentRect;
_each(that._cache, function(_, cacheItem) {
var options = cacheItem.options,
left,
top,
verticalOverlay = _Number(options.overlay) || 0;
switch (_String(options.verticalAlignment).toLowerCase()) {
case'bottom':
top = currentRect.bottom - verticalOverlay;
currentRect.bottom += _max(options.height - verticalOverlay, 0);
break;
default:
top = currentRect.top - options.height + verticalOverlay;
currentRect.top -= _max(options.height - verticalOverlay, 0);
break
}
switch (_String(options.horizontalAlignment).toLowerCase()) {
case'left':
left = rootRect.left;
break;
case'right':
left = rootRect.right - options.width;
break;
default:
left = rootRect.horizontalMiddle() - options.width / 2;
break
}
cacheItem.target.locate(left, top)
});
that._cache = null;
return that
},
selectRectByAspectRatio: function(aspectRatio, margins) {
var rect = this._currentRect.clone(),
selfAspectRatio,
width = 0,
height = 0;
margins = margins || {};
if (aspectRatio > 0) {
rect.left += margins.left || 0;
rect.right -= margins.right || 0;
rect.top += margins.top || 0;
rect.bottom -= margins.bottom || 0;
if (rect.width() > 0 && rect.height() > 0) {
selfAspectRatio = rect.height() / rect.width();
if (selfAspectRatio > 1)
aspectRatio < selfAspectRatio ? width = rect.width() : height = rect.height();
else
aspectRatio > selfAspectRatio ? height = rect.height() : width = rect.width();
width > 0 || (width = height / aspectRatio);
height > 0 || (height = width * aspectRatio);
width = (rect.width() - width) / 2;
height = (rect.height() - height) / 2;
rect.left += width;
rect.right -= width;
rect.top += height;
rect.bottom -= height
}
else {
rect.left = rect.right = rect.horizontalMiddle();
rect.top = rect.bottom = rect.verticalMiddle()
}
}
return rect
},
selectRectBySizes: function(sizes, margins) {
var rect = this._currentRect.clone(),
step;
margins = margins || {};
if (sizes) {
rect.left += margins.left || 0;
rect.right -= margins.right || 0;
rect.top += margins.top || 0;
rect.bottom -= margins.bottom || 0;
if (sizes.width > 0) {
step = (rect.width() - sizes.width) / 2;
if (step > 0) {
rect.left += step;
rect.right -= step
}
}
if (sizes.height > 0) {
step = (rect.height() - sizes.height) / 2;
if (step > 0) {
rect.top += step;
rect.bottom -= step
}
}
}
return rect
}
})
})(DevExpress, jQuery);
/*! Module viz-gauges, file themeManager.js */
(function(DX, $, undefined) {
var _extend = $.extend;
DX.viz.gauges.__internals.ThemeManager = DX.viz.core.BaseThemeManager.inherit({
_themeSection: 'gauge',
_initializeTheme: function() {
var that = this;
if (that._subTheme) {
var subTheme = _extend(true, {}, that._theme[that._subTheme], that._theme);
_extend(true, that._theme, subTheme)
}
that._initializeFont(that._theme.scale.label.font);
that._initializeFont(that._theme.valueIndicator.rangebar.text.font);
that._initializeFont(that._theme.subvalueIndicator.textcloud.text.font);
that._initializeFont(that._theme.valueIndicators.rangebar.text.font);
that._initializeFont(that._theme.valueIndicators.textcloud.text.font);
that._initializeFont(that._theme.title.font);
that._initializeFont(that._theme.subtitle.font);
that._initializeFont(that._theme.tooltip.font);
that._initializeFont(that._theme.indicator.text.font);
that._initializeFont(that._theme.loadingIndicator.font)
}
})
})(DevExpress, jQuery);
/*! Module viz-gauges, file presetManager.js */
/*! Module viz-gauges, file baseGauge.js */
(function(DX, $, undefined) {
var _Number = Number,
_isNumber = DX.utils.isNumber,
_isString = DX.utils.isString,
_getAppropriateFormat = DX.utils.getAppropriateFormat,
_extend = $.extend,
_each = $.each;
DX.viz.gauges.__internals.BaseGauge = DX.viz.core.BaseWidget.inherit({
_init: function() {
var that = this;
that.callBase.apply(that, arguments);
that._renderer = that._factory.createRenderer({
width: 1,
height: 1,
pathModified: that.option('pathModified'),
rtl: that.option('rtlEnabled')
});
that._root = that._renderer.getRoot();
that._root.applySettings({'class': 'dxg ' + that._rootClass});
that._translator = that._factory.createTranslator();
that._themeManager = that._factory.createThemeManager();
that._tracker = that._factory.createTracker({
renderer: that._renderer,
container: that._root
});
that._layoutManager = that._factory.createLayoutManager();
that._tooltip = that._factory.createTooltip({
renderer: that._renderer,
container: that._root,
tracker: that._tracker
});
that._title = that._factory.createTitle({
renderer: that._renderer,
container: that._root
});
that._deltaIndicator = that._factory.createDeltaIndicator({
renderer: that._renderer,
container: that._root
});
that._setupDomain();
that._themeManager.setTheme(that.option('theme'))
},
_dispose: function() {
var that = this;
that.callBase.apply(that, arguments);
that._renderer.dispose();
that._themeManager.dispose();
that._tracker.dispose();
that._title.dispose();
that._deltaIndicator && that._deltaIndicator.dispose();
that._tooltip.dispose();
that._disposeLoadIndicator();
that._renderer = that._root = that._translator = that._themeManager = that._tracker = that._layoutManager = that._title = that._tooltip = null
},
_refresh: function() {
var that = this,
callBase = that.callBase;
that._endLoading(function() {
callBase.call(that)
})
},
_clean: function() {
this._cleanCore()
},
_render: function() {
var that = this;
that._setupCodomain();
that._setupAnimationSettings();
if (that._calculateSize() && that._checkDomain()) {
that._renderer.draw(that._element()[0]);
that._setupDefaultFormat();
that._renderCore()
}
that._drawn()
},
_cleanCore: function() {
var that = this;
that._tooltip.clean();
that._title.clean();
that._deltaIndicator && that._deltaIndicator.clean();
that._tracker.deactivate();
that._cleanContent()
},
_renderCore: function() {
var that = this;
that._title.render(_extend(true, {}, that._themeManager.theme()['title'], processTitleOptions(that.option('title'))), _extend(true, {}, that._themeManager.theme()['subtitle'], processTitleOptions(that.option('subtitle'))));
that._deltaIndicator && that._deltaIndicator.render(_extend(true, {}, that._themeManager.theme()['indicator'], that.option('indicator')));
that._layoutManager.beginLayout(that._rootRect);
_each([that._deltaIndicator, that._title], function(_, item) {
item && that._layoutManager.applyLayout(item)
});
that._mainRect = that._layoutManager.getRect();
that._renderContent();
that._layoutManager.endLayout();
that._tooltip.render(_extend(true, {}, that._themeManager.theme()['tooltip'], that.option('tooltip')), {
width: that._width,
height: that._height
});
that._tracker.activate();
that._updateLoadIndicator(undefined, that._width, that._height);
that._noAnimation = null;
that.option('debugMode') === true && that._renderDebugInfo();
that._debug_rendered && that._debug_rendered()
},
_renderDebugInfo: function() {
var that = this,
group = that._debugGroup || that._renderer.createGroup({'class': 'debug-info'}).append(),
rect;
group.clear();
rect = that._rootRect;
that._renderer.createRect(rect.left, rect.top, rect.width(), rect.height(), 0, {
stroke: '#000000',
strokeWidth: 1,
fill: 'none'
}).append(group);
rect = that._mainRect;
that._renderer.createRect(rect.left, rect.top, rect.width(), rect.height(), 0, {
stroke: '#0000FF',
strokeWidth: 1,
fill: 'none'
}).append(group);
rect = that._layoutManager.getRect();
rect && that._renderer.createRect(rect.left, rect.top, rect.width(), rect.height(), 0, {
stroke: '#FF0000',
strokeWidth: 1,
fill: 'none'
}).append(group);
rect = that._title.getLayoutOptions() ? that._title._root.getBBox() : null;
rect && that._renderer.createRect(rect.x, rect.y, rect.width, rect.height, 0, {
stroke: '#00FF00',
strokeWidth: 1,
fill: 'none'
}).append(group);
rect = that._deltaIndicator && that._deltaIndicator.getLayoutOptions() ? that._deltaIndicator._root.getBBox() : null;
rect && that._renderer.createRect(rect.x, rect.y, rect.width, rect.height, 0, {
stroke: '#00FF00',
strokeWidth: 1,
fill: 'none'
}).append(group)
},
_resize: function() {
var that = this;
if (that._calculateSize()) {
that._resizing = that._noAnimation = true;
that._cleanCore();
that._renderCore();
that._resizing = null
}
},
render: function(options) {
options && options.animate !== undefined && !options.animate && (this._noAnimation = true);
this._refresh();
return this
},
showLoadingIndicator: function() {
this._showLoadIndicator(this._getLoadIndicatorOption(), {
width: this._width,
height: this._height
})
},
_getLoadIndicatorOption: function() {
return _extend(true, {}, this._themeManager.theme()['loadingIndicator'], this.option('loadingIndicator'))
},
_optionChanged: function(name, newv, oldv) {
var that = this;
switch (name) {
case'theme':
that._themeManager.setTheme(newv);
that._invalidate();
break;
case'startValue':
case'endValue':
that._setupDomain();
that._invalidate();
break;
default:
that.callBase.apply(that, arguments);
break
}
},
_calculateSize: function() {
var that = this;
that._calculateSizeCore();
if (that._width === 0 || that._height === 0 || !that._element().is(':visible')) {
that._incidentOccured('W2001', [that.NAME]);
return false
}
else {
that._renderer.resize(that._width, that._height);
return true
}
},
_checkDomain: function() {
var that = this,
domain = that._translator.getDomain(),
isValid = isFinite(1 / (domain[1] - domain[0]));
if (!isValid)
that._incidentOccured('W2301');
return isValid
},
_setupAnimationSettings: function() {
var that = this,
option = that.option('animation');
that._animationSettings = null;
if (option === undefined || option) {
if (option === undefined)
option = {
enabled: that.option('animationEnabled'),
duration: that.option('animationDuration')
};
option = _extend({
enabled: true,
duration: 1000,
easing: 'easeOutCubic'
}, option);
if (option.enabled && option.duration > 0)
that._animationSettings = {
duration: _Number(option.duration),
easing: option.easing
}
}
that._containerBackgroundColor = that.option('containerBackgroundColor') || that._themeManager.theme().containerBackgroundColor
},
_setupDefaultFormat: function() {
var domain = this._translator.getDomain();
this._defaultFormatOptions = _getAppropriateFormat(domain[0], domain[1], this._getApproximateScreenRange())
},
_setupDomain: null,
_calculateSizeCore: null,
_cleanContent: null,
_renderContent: null,
_setupCodomain: null,
_getApproximateScreenRange: null,
_factory: {
createRenderer: DX.viz.core.CoreFactory.createRenderer,
createTranslator: function() {
return new DX.viz.core.Translator1D
},
createTracker: function(parameters) {
return new DX.viz.gauges.__internals.Tracker(parameters)
},
createLayoutManager: function() {
return new DX.viz.gauges.__internals.LayoutManager
},
createTitle: function(parameters) {
return new DX.viz.gauges.__internals.Title(parameters)
},
createDeltaIndicator: function(parameters) {
return DX.viz.gauges.__internals.DeltaIndicator ? new DX.viz.gauges.__internals.DeltaIndicator(parameters) : null
},
createTooltip: function(parameters) {
return new DX.viz.gauges.__internals.Tooltip(parameters)
}
}
});
function processTitleOptions(options) {
return _isString(options) ? {text: options} : options || {}
}
})(DevExpress, jQuery);
/*! Module viz-gauges, file gauge.js */
(function(DX, $, undefined) {
var _Rectangle = DX.viz.core.Rectangle;
var _isDefined = DX.utils.isDefined,
_isArray = DX.utils.isArray,
_isNumber = DX.utils.isNumber,
_isFinite = isFinite,
_Number = Number,
_String = String,
_abs = Math.abs,
_extend = $.extend,
_each = $.each,
_map = $.map,
_noop = $.noop;
var OPTION_VALUE = 'value',
OPTION_SUBVALUES = 'subvalues';
DX.viz.gauges.Gauge = DX.viz.gauges.__internals.BaseGauge.inherit({
_init: function() {
var that = this;
that.__value = that.option(OPTION_VALUE);
that.__subvalues = that.option(OPTION_SUBVALUES);
if (!_isArray(that.__subvalues))
that.__subvalues = _isNumber(that.__subvalues) ? [that.__subvalues] : null;
that._selectMode();
that.callBase.apply(that, arguments);
that._scale = that._createScale({
renderer: that._renderer,
container: that._root,
translator: that._translator
});
that._rangeContainer = that._createRangeContainer({
renderer: that._renderer,
container: that._root,
translator: that._translator
})
},
_dispose: function() {
var that = this;
that.callBase.apply(that, arguments);
that._scale.dispose();
that._rangeContainer.dispose();
that._disposeValueIndicators();
that._scale = that._rangeContainer = null
},
_disposeValueIndicators: function() {
var that = this;
that._valueIndicator && that._valueIndicator.dispose();
that._subvalueIndicatorsSet && that._subvalueIndicatorsSet.dispose();
that._valueIndicator = that._subvalueIndicatorsSet = null
},
_selectMode: function() {
var that = this;
if (that.option(OPTION_VALUE) === undefined && that.option(OPTION_SUBVALUES) === undefined)
if (that.option('needles') !== undefined || that.option('markers') !== undefined || that.option('rangeBars') !== undefined) {
disableDefaultMode(that);
selectObsoleteMode(that)
}
else if (that.option('valueIndicators') !== undefined) {
disableDefaultMode(that);
selectHardMode(that)
}
},
_setupDomain: function() {
var that = this,
scaleOption = that.option('scale') || {},
startValue = that.option('startValue'),
endValue = that.option('endValue');
startValue = _isNumber(startValue) ? _Number(startValue) : _isNumber(scaleOption.startValue) ? _Number(scaleOption.startValue) : 0;
endValue = _isNumber(endValue) ? _Number(endValue) : _isNumber(scaleOption.endValue) ? _Number(scaleOption.endValue) : 100;
that._baseValue = startValue < endValue ? startValue : endValue;
that._translator.setDomain(startValue, endValue);
that._setupValueState()
},
_setupValueState: function() {
this._setupValue();
this.__subvalues !== null && this._setupSubvalues()
},
_calculateSizeCore: function() {
var that = this,
size = that.option('size') || {},
margin = that.option('margin') || {};
if (_Number(size.width) === 0 || _Number(size.height) === 0) {
that._width = that._height = 0;
that._rootRect = new _Rectangle
}
else {
var width = size.width > 0 ? _Number(size.width) : that._element().width() || that._getDefaultContainerSize().width,
height = size.height > 0 ? _Number(size.height) : that._element().height() || that._getDefaultContainerSize().height,
marginL = margin.left > 0 ? _Number(margin.left) : 0,
marginR = margin.right > 0 ? _Number(margin.right) : 0,
marginT = margin.top > 0 ? _Number(margin.top) : 0,
marginB = margin.bottom > 0 ? _Number(margin.bottom) : 0;
marginL + marginR >= width && (marginL = marginR = 0);
marginT + marginB >= height && (marginT = marginB = 0);
that._width = width;
that._height = height;
that._rootRect = new _Rectangle({
left: marginL,
top: marginT,
right: width - marginR,
bottom: height - marginB
})
}
},
_cleanContent: function() {
var that = this;
that._rangeContainer.clean();
that._scale.clean();
that._cleanValueIndicators()
},
_renderContent: function() {
var that = this;
that._rangeContainer.render(_extend(true, {}, that._themeManager.theme().rangeContainer, that.option('rangeContainer'), {
themeName: that._themeManager.themeName(),
vertical: that._area.vertical
}));
that._scale.render(_extend(true, {}, that._themeManager.theme().scale, that.option('scale'), {
approximateScreenDelta: that._getApproximateScreenRange(),
offset: 0,
vertical: that._area.vertical
}));
var elements = that._prepareValueIndicators();
elements = _map([that._scale, that._rangeContainer].concat(elements), function(element) {
return element && element.enabled ? element : null
});
that._applyMainLayout(elements);
_each(elements, function(_, element) {
that._updateElementPosition(element)
});
that._updateActiveElements()
},
_updateIndicatorSettings: function(settings) {
var that = this;
settings.currentValue = settings.baseValue = _isFinite(that._translator.translate(settings.baseValue)) ? _Number(settings.baseValue) : that._baseValue;
settings.vertical = that._area.vertical;
if (settings.text && !settings.text.format && !settings.text.precision) {
settings.text.format = that._defaultFormatOptions.format;
settings.text.precision = that._defaultFormatOptions.precision
}
},
_prepareValueIndicatorSettings: function() {
var that = this,
options = that.option('valueIndicator') || {},
defaultOptions = _extend(true, {}, that._themeManager.theme().valueIndicator),
type = _String(options.type || defaultOptions.type).toLowerCase();
that._valueIndicatorSettings = _extend(true, defaultOptions._default, defaultOptions[type], options, {
type: type,
animation: that._animationSettings,
containerBackgroundColor: that._containerBackgroundColor
});
that._updateIndicatorSettings(that._valueIndicatorSettings)
},
_prepareSubvalueIndicatorSettings: function() {
var that = this,
options = that.option('subvalueIndicator') || {},
defaultOptions = _extend(true, {}, that._themeManager.theme().subvalueIndicator),
type = _String(options.type || defaultOptions.type).toLowerCase();
that._subvalueIndicatorSettings = _extend(true, defaultOptions._default, defaultOptions[type], options, {
type: type,
animation: that._animationSettings,
containerBackgroundColor: that._containerBackgroundColor
});
that._updateIndicatorSettings(that._subvalueIndicatorSettings)
},
_cleanValueIndicators: function() {
this._valueIndicator && this._valueIndicator.clean();
this._subvalueIndicatorsSet && this._subvalueIndicatorsSet.clean()
},
_prepareValueIndicators: function() {
var that = this;
that._prepareValueIndicator();
that.__subvalues !== null && that._prepareSubvalueIndicators();
return [that._valueIndicator, that._subvalueIndicatorsSet]
},
_updateActiveElements: function() {
this._updateValueIndicator();
this._updateSubvalueIndicators()
},
_prepareValueIndicator: function() {
var that = this,
indicator = that._valueIndicator,
currentValue;
that._prepareValueIndicatorSettings();
indicator && that._valueIndicatorType !== that._valueIndicatorSettings.type && indicator.dispose() && (indicator = null);
that._valueIndicatorType = that._valueIndicatorSettings.type;
if (!indicator) {
indicator = that._valueIndicator = that._createValueIndicator(that._valueIndicatorType);
if (indicator) {
indicator.setup({
renderer: that._renderer,
translator: that._translator,
owner: that._root,
tracker: that._tracker,
className: 'dxg-value-indicator'
});
indicator._trackerInfo = {type: 'value-indicator'}
}
}
indicator.render(that._valueIndicatorSettings)
},
_prepareSubvalueIndicators: function() {
var that = this,
subvalueIndicatorsSet = that._subvalueIndicatorsSet;
if (!subvalueIndicatorsSet)
subvalueIndicatorsSet = that._subvalueIndicatorsSet = new DX.viz.gauges.__internals.ValueIndicatorsSet({
renderer: that._renderer,
translator: that._translator,
owner: that._root,
tracker: that._tracker,
className: 'dxg-subvalue-indicators',
indicatorClassName: 'dxg-subvalue-indicator',
trackerType: 'subvalue-indicator',
createIndicator: function() {
return that._createSubvalueIndicator(that._subvalueIndicatorType)
}
});
that._prepareSubvalueIndicatorSettings();
var isRecreate = that._subvalueIndicatorSettings.type !== that._subvalueIndicatorType;
that._subvalueIndicatorType = that._subvalueIndicatorSettings.type;
if (that._createSubvalueIndicator(that._subvalueIndicatorType))
subvalueIndicatorsSet.render(that._subvalueIndicatorSettings, isRecreate)
},
_processValue: function(value, fallbackValue) {
var _value = this._translator.adjust(value !== undefined ? value : this.__value);
return _isFinite(_value) ? _value : fallbackValue
},
_setupValue: function(value) {
this.__value = this._processValue(value, this.__value)
},
_setupSubvalues: function(subvalues) {
var _subvalues = subvalues === undefined ? this.__subvalues : _isArray(subvalues) ? subvalues : _isNumber(subvalues) ? [subvalues] : null;
if (_subvalues === null)
return;
var i = 0,
ii = _subvalues.length,
list = [];
for (; i < ii; ++i)
list.push(this._processValue(_subvalues[i], this.__subvalues[i]));
this.__subvalues = list
},
_updateValueIndicator: function() {
var that = this;
that._valueIndicator && that._valueIndicator.value(that.__value, that._noAnimation);
that._resizing || that.hideLoadingIndicator()
},
_updateSubvalueIndicators: function() {
var that = this;
that._subvalueIndicatorsSet && that._subvalueIndicatorsSet.values(that.__subvalues, that._noAnimation);
that._resizing || that.hideLoadingIndicator()
},
value: function(arg) {
var that = this;
if (arg !== undefined) {
that._setupValue(arg);
that._updateValueIndicator();
that.option(OPTION_VALUE, that.__value);
return that
}
return that.__value
},
subvalues: function(arg) {
var that = this;
if (arg !== undefined) {
if (that.__subvalues !== null) {
that._setupSubvalues(arg);
that._updateSubvalueIndicators();
that.option(OPTION_SUBVALUES, that.__subvalues)
}
return that
}
return that.__subvalues !== null ? that.__subvalues.slice() : undefined
},
_handleValueChanged: function(name, newv, oldv) {
var that = this;
switch (name) {
case OPTION_VALUE:
that._setupValue(newv);
that._updateValueIndicator();
that.option(OPTION_VALUE, that.__value);
return true;
case OPTION_SUBVALUES:
if (that.__subvalues !== null) {
that._setupSubvalues(newv);
that._updateSubvalueIndicators();
that.option(OPTION_SUBVALUES, that.__subvalues);
return true
}
return false;
default:
return false
}
},
_optionChanged: function(name, newValue, oldValue) {
var that = this;
if (that._handleValueChanged(name, newValue, oldValue))
return;
switch (name) {
case'scale':
that._setupDomain();
that._invalidate();
break;
default:
that.callBase.apply(that, arguments);
break
}
},
_optionValuesEqual: function(name, oldValue, newValue) {
switch (name) {
case OPTION_VALUE:
return oldValue === newValue;
case OPTION_SUBVALUES:
return compareArrays(oldValue, newValue);
default:
return this.callBase.apply(this, arguments)
}
},
_getDefaultContainerSize: null,
_applyMainLayout: null,
_updateElementPosition: null,
_createScale: null,
_createRangeContainer: null,
_createValueIndicator: null,
_createSubvalueIndicator: null,
_getApproximateScreenRange: null
});
DX.viz.gauges.Gauge.prototype._factory = DX.utils.clone(DX.viz.gauges.__internals.BaseGauge.prototype._factory);
DX.viz.gauges.Gauge.prototype._factory.createThemeManager = function() {
return new DX.viz.gauges.__internals.ThemeManager
};
function valueGetter(arg) {
return arg.value
}
function setupValues(that, fieldName, optionItems) {
var currentValues = that[fieldName],
newValues = _isArray(optionItems) ? _map(optionItems, valueGetter) : [],
i = 0,
ii = newValues.length,
list = [];
for (; i < ii; ++i)
list.push(that._processValue(newValues[i], currentValues[i]));
that[fieldName] = list
}
function disableDefaultMode(that) {
that.value = that.subvalues = _noop;
that._setupValue = that._setupSubvalues = that._updateValueIndicator = that._updateSubvalueIndicators = null
}
function selectObsoleteMode(that) {
that._needleValues = _map(that.option('needles') || [], valueGetter);
that._markerValues = _map(that.option('markers') || [], valueGetter);
that._rangeBarValues = _map(that.option('rangeBars') || [], valueGetter);
that._needles = [];
that._markers = [];
that._rangeBars = [];
that._setupValueState = function() {
var that = this;
setupValues(that, '_needleValues', that.option('needles'));
setupValues(that, '_markerValues', that.option('markers'));
setupValues(that, '_rangeBarValues', that.option('rangeBars'))
};
that._handleValueChanged = function(name, newv, oldv) {
var that = this,
result = false;
switch (name) {
case'needles':
setupValues(that, '_needleValues', newv);
result = true;
break;
case'markers':
setupValues(that, '_markerValues', newv);
result = true;
break;
case'rangeBars':
setupValues(that, '_rangeBarValues', newv);
result = true;
break
}
result && that._invalidate();
return result
};
that._updateActiveElements = function() {
var that = this;
_each(that._needles, function(_, needle) {
needle.value(that._needleValues[needle._index], that._noAnimation)
});
_each(that._markers, function(_, marker) {
marker.value(that._markerValues[marker._index], that._noAnimation)
});
_each(that._rangeBars, function(_, rangeBar) {
rangeBar.value(that._rangeBarValues[rangeBar._index], that._noAnimation)
});
that._resizing || that.hideLoadingIndicator()
};
that._prepareValueIndicators = function() {
return prepareObsoleteElements(this)
};
that._disposeValueIndicators = function() {
var that = this;
_each([].concat(that._needles, that._markers, that._rangeBars), function(_, pointer) {
pointer.dispose()
});
that._needles = that._markers = that._rangeBars = null
};
that._cleanValueIndicators = function() {
_each([].concat(this._needles, this._markers, this._rangeBars), function(_, pointer) {
pointer.clean()
})
};
that.needleValue = function(index, value) {
return accessPointerValue(this, this._needles, this._needleValues, index, value)
};
that.markerValue = function(index, value) {
return accessPointerValue(this, this._markers, this._markerValues, index, value)
};
that.rangeBarValue = function(index, value) {
return accessPointerValue(this, this._rangeBars, this._rangeBarValues, index, value)
}
}
function selectHardMode(that) {
that._indicatorValues = [];
that._valueIndicators = [];
that._setupValueState = function() {
setupValues(this, '_indicatorValues', this.option('valueIndicators'))
};
that._handleValueChagned = function(name, newv, oldv) {
if (name === 'valueIndicators') {
setupValues(this, '_indicatorValues', newv);
this._invalidate();
return true
}
return false
};
that._updateActiveElements = function() {
var that = this;
_each(that._valueIndicators, function(_, valueIndicator) {
valueIndicator.value(that._indicatorValues[valueIndicator._index], that._noAnimation)
});
that._resizing || that.hideLoadingIndicator()
};
that._prepareValueIndicators = function() {
return prepareValueIndicatorsInHardMode(this)
};
that._disposeValueIndicators = function() {
_each(this._valueIndicators, function(_, valueIndicator) {
valueIndicator.dispose()
});
this._valueIndicators = null
};
that._cleanValueIndicators = function() {
_each(this._valueIndicators, function(_, valueIndicator) {
valueIndicator.clean()
})
};
that.indicatorValue = function(index, value) {
return accessPointerValue(this, this._valueIndicators, this._indicatorValues, index, value)
}
}
function prepareValueIndicatorsInHardMode(that) {
var valueIndicators = that._valueIndicators || [],
userOptions = that.option('valueIndicators'),
optionList = [],
i = 0,
ii;
for (ii = _isArray(userOptions) ? userOptions.length : 0; i < ii; ++i)
optionList.push(userOptions[i]);
for (ii = valueIndicators.length; i < ii; ++i)
optionList.push(null);
var themeSettings = that._themeManager.theme().valueIndicators,
parameters = {
renderer: that._renderer,
owner: that._root,
translator: that._translator,
tracker: that._tracker
},
newValueIndicators = [];
_each(optionList, function(i, userSettings) {
var valueIndicator = valueIndicators[i];
if (!userSettings) {
valueIndicator && valueIndicator.dispose();
return
}
var type = _String(userSettings.type || themeSettings._type).toLowerCase();
if (valueIndicator && type !== valueIndicator.type) {
valueIndicator.dispose();
valueIndicator = null
}
if (!valueIndicator) {
valueIndicator = that._createValueIndicatorInHardMode(type);
valueIndicator && valueIndicator.setup(parameters)
}
if (valueIndicator) {
var settings = _extend(true, {}, themeSettings._default, themeSettings[type], userSettings, {
type: type,
animation: that._animationSettings,
containerBackgroundColor: that._containerBackgroundColor
});
that._updateIndicatorSettings(settings);
valueIndicator.render(settings);
valueIndicator._index = i;
valueIndicator._trackerInfo = {index: i};
newValueIndicators.push(valueIndicator)
}
});
that._valueIndicators = newValueIndicators;
return that._valueIndicators
}
function prepareObsoleteElements(that) {
var rangeBars = prepareObsoletePointers(that, '_rangeBars', '_createRangeBar', {
user: that.option('rangeBars'),
common: that.option('commonRangeBarSettings'),
theme: that._themeManager.theme().valueIndicator,
preset: {},
type: 'rangebar',
className: 'dxg-value-indicator'
});
var needles = prepareObsoletePointers(that, '_needles', '_createNeedle', {
user: that.option('needles'),
common: that.option('commonNeedleSettings'),
theme: that._themeManager.theme().valueIndicator,
preset: that._getPreset().commonNeedleSettings,
className: 'dxg-value-indicator'
});
var markers = prepareObsoletePointers(that, '_markers', '_createMarker', {
user: that.option('markers'),
common: that.option('commonMarkerSettings'),
theme: that._themeManager.theme().subvalueIndicator,
preset: that._getPreset().commonMarkerSettings,
className: 'dxg-subvalue-indicator'
});
var spindle = that._prepareObsoleteSpindle && that._prepareObsoleteSpindle();
return [].concat(rangeBars, needles, markers, [spindle])
}
function prepareObsoletePointers(that, fieldName, methodName, options) {
var pointers = that[fieldName],
userOptions = [],
i = 0,
ii;
for (ii = _isArray(options.user) ? options.user.length : 0; i < ii; ++i)
userOptions.push(options.user[i]);
for (ii = pointers.length; i < ii; ++i)
userOptions.push(null);
var themeOption = options.theme,
presetOption = options.preset,
commonOption = options.common || {},
parameters = {
renderer: that._renderer,
owner: that._root,
translator: that._translator,
tracker: that._tracker,
className: options.className
},
newPointers = [];
_each(userOptions, function(i, pointerOption) {
var pointer = pointers[i];
if (!pointerOption) {
pointer && pointer.dispose();
return
}
var type = _String(pointerOption.type || commonOption.type || presetOption.type || themeOption.type).toLowerCase(),
settings;
if (pointer && pointer.type !== type) {
pointer.dispose();
pointer = null
}
if (!pointer) {
pointer = that[methodName](type);
pointer.setup(parameters)
}
if (pointer) {
type = options.type || type;
settings = _extend(true, {}, themeOption._default, themeOption[type], commonOption, pointerOption),
settings.spindleSize = null;
settings.animation = that._animationSettings;
settings.containerBackgroundColor = that._containerBackgroundColor;
that._updateIndicatorSettings(settings);
pointer.render(settings);
pointer._index = i;
pointer._trackerInfo = {index: i};
newPointers.push(pointer)
}
});
that[fieldName] = newPointers;
return newPointers
}
function accessPointerValue(that, pointers, values, index, value) {
if (value !== undefined) {
if (values[index] !== undefined) {
values[index] = that._processValue(value, values[index]);
pointers[index] && pointers[index].value(values[index]);
that._resizing || that.hideLoadingIndicator()
}
return that
}
else
return values[index]
}
function compareArrays(array1, array2) {
if (array1 === array2)
return true;
if (_isArray(array1) && _isArray(array2) && array1.length === array2.length) {
for (var i = 0, ii = array1.length; i < ii; ++i)
if (_abs(array1[i] - array2[i]) > 1E-8)
return false;
return true
}
return false
}
DX.viz.gauges.__internals.ValueIndicatorsSet = DX.Class.inherit({
ctor: function(parameters) {
var that = this;
that._parameters = parameters;
that._createIndicator = that._parameters.createIndicator || _noop;
that._root = that._parameters.renderer.createGroup({'class': that._parameters.className});
that._indicatorParameters = that._indicatorParameters || {
renderer: that._parameters.renderer,
translator: that._parameters.translator,
owner: that._root,
tracker: that._parameters.tracker,
className: that._parameters.indicatorClassName
};
that._indicators = []
},
dispose: function() {
var that = this;
_each(that._indicators, function(_, indicator) {
indicator.dispose()
});
that._parameters = that._createIndicator = that._root = that._options = that._indicators = that._colorPalette = that._palette = null;
return that
},
clean: function() {
var that = this;
that._root.detach();
that._sample && that._sample.clean().dispose();
_each(that._indicators, function(_, indicator) {
indicator.clean()
});
that._sample = that._options = that._palette = null;
return that
},
render: function(options, isRecreate) {
var that = this;
that._options = options;
that._sample = that._createIndicator();
that._sample && that._sample.setup(that._indicatorParameters).render(options);
that.enabled = that._sample && that._sample.enabled;
that._palette = _isDefined(options.palette) ? new DX.viz.core.Palette(options.palette) : null;
if (that.enabled) {
that._root.append(that._parameters.owner);
that._generatePalette(that._indicators.length);
that._indicators = _map(that._indicators, function(indicator, i) {
if (isRecreate) {
indicator.dispose();
indicator = that._createIndicator();
indicator.setup(that._indicatorParameters);
indicator._trackerInfo = {
type: that._parameters.trackerType,
index: i
}
}
indicator.render(that._getIndicatorOptions(i));
return indicator
})
}
return that
},
resize: function(layout) {
var that = this;
that._layout = layout;
_each(that._indicators, function(_, indicator) {
indicator.resize(layout)
});
return that
},
measure: function(layout) {
return this._sample.measure(layout)
},
_getIndicatorOptions: function(index) {
var result = this._options;
if (this._colorPalette)
result = _extend({}, result, {color: this._colorPalette[index]});
return result
},
_generatePalette: function(count) {
var that = this,
colors = null;
if (that._palette) {
colors = [];
that._palette.reset();
var i = 0;
for (; i < count; ++i)
colors.push(that._palette.getNextColor())
}
that._colorPalette = colors
},
_adjustIndicatorsCount: function(count) {
var that = this,
indicators = that._indicators,
i,
ii,
indicatorOptions,
indicator,
indicatorsLen = indicators.length,
palette = that._parameters.palette;
if (indicatorsLen > count) {
for (i = count, ii = indicatorsLen; i < ii; ++i)
indicators[i].clean().dispose();
that._indicators = indicators.slice(0, count);
that._generatePalette(indicators.length)
}
else if (indicatorsLen < count) {
that._generatePalette(count);
for (i = indicatorsLen, ii = count; i < ii; ++i) {
indicator = that._createIndicator();
indicator.setup(that._indicatorParameters);
indicator._trackerInfo = {
type: that._parameters.trackerType,
index: i
};
indicator.render(that._getIndicatorOptions(i)).resize(that._layout);
indicators.push(indicator)
}
}
},
values: function(arg, _noAnimation) {
var that = this;
if (!that.enabled)
return;
if (arg !== undefined) {
if (!_isArray(arg))
arg = _isFinite(arg) ? [Number(arg)] : null;
if (arg) {
that._adjustIndicatorsCount(arg.length);
_each(that._indicators, function(i, indicator) {
indicator.value(arg[i], _noAnimation)
})
}
return that
}
return _map(that._indicators, function(indicator) {
return indicator.value()
})
}
})
})(DevExpress, jQuery);
/*! Module viz-gauges, file circularGauge.js */
(function(DX, $, undefined) {
var factory = DX.viz.gauges.__factory;
var isFinite = window.isFinite,
Number = window.Number,
normalizeAngle = DX.utils.normalizeAngle,
getCosAndSin = DX.utils.getCosAndSin,
abs = Math.abs,
max = Math.max,
min = Math.min,
round = Math.round,
slice = Array.prototype.slice,
$extend = $.extend,
$each = $.each;
var PI = Math.PI;
function getSides(startAngle, endAngle) {
var startCosSin = getCosAndSin(startAngle),
endCosSin = getCosAndSin(endAngle),
startCos = startCosSin.cos,
startSin = startCosSin.sin,
endCos = endCosSin.cos,
endSin = endCosSin.sin;
return {
left: startSin <= 0 && endSin >= 0 || startSin <= 0 && endSin <= 0 && startCos <= endCos || startSin >= 0 && endSin >= 0 && startCos >= endCos ? -1 : min(startCos, endCos, 0),
right: startSin >= 0 && endSin <= 0 || startSin >= 0 && endSin >= 0 && startCos >= endCos || startSin <= 0 && endSin <= 0 && startCos <= endCos ? 1 : max(startCos, endCos, 0),
up: startCos <= 0 && endCos >= 0 || startCos <= 0 && endCos <= 0 && startSin >= endSin || startCos >= 0 && endCos >= 0 && startSin <= endSin ? -1 : -max(startSin, endSin, 0),
down: startCos >= 0 && endCos <= 0 || startCos >= 0 && endCos >= 0 && startSin <= endSin || startCos <= 0 && endCos <= 0 && startSin >= endSin ? 1 : -min(startSin, endSin, 0)
}
}
DX.viz.gauges.CircularGauge = DX.viz.gauges.Gauge.inherit({
_rootClass: 'dxg-circular-gauge',
_selectMode: function() {
this.callBase.apply(this, arguments);
if (typeof this.indicatorValue === 'function')
this._createValueIndicatorInHardMode = function(type) {
return factory.createCircularValueIndicatorInHardMode(type)
}
},
_setupCodomain: function() {
var that = this,
geometry = that.option('geometry') || {},
startAngle = geometry.startAngle,
endAngle = geometry.endAngle,
sides;
startAngle = isFinite(startAngle) ? normalizeAngle(startAngle) : 225;
endAngle = isFinite(endAngle) ? normalizeAngle(endAngle) : -45;
if (abs(startAngle - endAngle) < 1) {
endAngle -= 360;
sides = {
left: -1,
up: -1,
right: 1,
down: 1
}
}
else {
startAngle < endAngle && (endAngle -= 360);
sides = getSides(startAngle, endAngle)
}
that._area = {
x: 0,
y: 0,
radius: 100,
startCoord: startAngle,
endCoord: endAngle,
scaleRadius: geometry.scaleRadius > 0 ? Number(geometry.scaleRadius) : undefined,
sides: sides
};
that._translator.setCodomain(startAngle, endAngle)
},
_measureMainElements: function(elements) {
var that = this,
maxRadius = 0,
minRadius = Infinity,
maxHorizontalOffset = 0,
maxVerticalOffset = 0,
maxInverseHorizontalOffset = 0,
maxInverseVerticalOffset = 0;
$each(elements, function(_, element) {
var bounds = element.measure({radius: that._area.radius - (Number(element._options.offset) || 0)});
bounds.min > 0 && (minRadius = min(minRadius, bounds.min));
bounds.max > 0 && (maxRadius = max(maxRadius, bounds.max));
bounds.horizontalOffset > 0 && (maxHorizontalOffset = max(maxHorizontalOffset, bounds.max + bounds.horizontalOffset));
bounds.verticalOffset > 0 && (maxVerticalOffset = max(maxVerticalOffset, bounds.max + bounds.verticalOffset));
bounds.inverseHorizontalOffset > 0 && (maxInverseHorizontalOffset = max(maxInverseHorizontalOffset, bounds.inverseHorizontalOffset));
bounds.inverseVerticalOffset > 0 && (maxInverseVerticalOffset = max(maxInverseVerticalOffset, bounds.inverseVerticalOffset))
});
maxHorizontalOffset = max(maxHorizontalOffset - maxRadius, 0);
maxVerticalOffset = max(maxVerticalOffset - maxRadius, 0);
return {
minRadius: minRadius,
maxRadius: maxRadius,
horizontalMargin: maxHorizontalOffset,
verticalMargin: maxVerticalOffset,
inverseHorizontalMargin: maxInverseHorizontalOffset,
inverseVerticalMargin: maxInverseVerticalOffset
}
},
_applyMainLayout: function(elements) {
var that = this,
measurements = that._measureMainElements(elements),
area = that._area,
sides = area.sides,
margins = {
left: (sides.left < -0.1 ? measurements.horizontalMargin : measurements.inverseHorizontalMargin) || 0,
right: (sides.right > 0.1 ? measurements.horizontalMargin : measurements.inverseHorizontalMargin) || 0,
top: (sides.up < -0.1 ? measurements.verticalMargin : measurements.inverseVerticalMargin) || 0,
bottom: (sides.down > 0.1 ? measurements.verticalMargin : measurements.inverseVerticalMargin) || 0
},
rect = that._layoutManager.selectRectByAspectRatio((sides.down - sides.up) / (sides.right - sides.left), margins),
radius = min(rect.width() / (sides.right - sides.left), rect.height() / (sides.down - sides.up)),
x,
y;
var scaler = (measurements.maxRadius - area.radius + area.scaleRadius) / radius;
if (0 < scaler && scaler < 1) {
rect = rect.scale(scaler);
radius *= scaler
}
radius = radius - measurements.maxRadius + area.radius;
x = rect.left - rect.width() * sides.left / (sides.right - sides.left);
y = rect.top - rect.height() * sides.up / (sides.down - sides.up);
area.x = round(x);
area.y = round(y);
area.radius = radius;
rect.left -= margins.left;
rect.right += margins.right;
rect.top -= margins.top;
rect.bottom += margins.bottom;
that._layoutManager.setRect(rect)
},
_updateElementPosition: function(element) {
element.resize({
x: this._area.x,
y: this._area.y,
radius: round(this._area.radius - (Number(element._options.offset) || 0))
})
},
_createScale: function(parameters) {
return factory.createCircularScale(parameters)
},
_createRangeContainer: function(parameters) {
return factory.createCircularRangeContainer(parameters)
},
_createValueIndicator: function(type) {
return factory.createCircularValueIndicator(type)
},
_createSubvalueIndicator: function(type) {
return factory.createCircularSubvalueIndicator(type)
},
_getApproximateScreenRange: function() {
var that = this,
area = that._area,
r = min(that._width / (area.sides.right - area.sides.left), that._height / (area.sides.down - area.sides.up));
r > area.totalRadius && (r = area.totalRadius);
r = 0.8 * r;
return -that._translator.getCodomainRange() * r * PI / 180
},
_getDefaultContainerSize: function() {
return {
width: 300,
height: 300
}
},
_getPreset: function() {
var preset = this.option('preset'),
result;
if (preset === 'preset2')
result = {
commonNeedleSettings: {type: 'twocolorrectangle'},
commonMarkerSettings: {type: 'triangle'}
};
else if (preset === 'preset3')
result = {
commonNeedleSettings: {type: 'rectangle'},
commonMarkerSettings: {type: 'triangle'}
};
else
result = {
commonNeedleSettings: {type: 'rectangle'},
commonMarkerSettings: {type: 'textcloud'}
};
return result
},
_createNeedle: function(type) {
return factory.createCircularNeedle(type)
},
_createMarker: function(type) {
return factory.createCircularMarker(type)
},
_createRangeBar: function() {
return factory.createCircularRangeBar()
},
_prepareObsoleteSpindle: function() {
var that = this,
spindleOption = that.option('spindle') || {},
visible = that._needles && ('visible' in spindleOption ? !!spindleOption.visible : true);
if (visible) {
var themeOption = that._themeManager.theme().valueIndicator._default,
size = spindleOption.size || themeOption.spindleSize;
visible = size > 0
}
if (visible) {
var gapSize = spindleOption.gapSize || themeOption.spindleGapSize,
color = spindleOption.color || themeOption.color;
gapSize = gapSize <= size ? gapSize : size;
that._spindle = that._spindle || that._renderer.createGroup({'class': 'dxg-value-indicator'});
that._spindle.append(that._root);
that._spindleOuter = that._spindleOuter || that._renderer.createCircle(0, 0, 0, {
'class': 'dxg-spindle-border',
stroke: 'none',
strokeWidth: 0
}).append(that._spindle);
that._spindleInner = that._spindleInner || that._renderer.createCircle(0, 0, 0, {
'class': 'dxg-spindle-hole',
stroke: 'none',
strokeWidth: 0
}).append(that._spindle);
that._spindleOuter.applySettings({
cx: that._area.x,
cy: that._area.y,
r: size / 2,
fill: color
});
that._spindleInner.applySettings({
cx: that._area.x,
cy: that._area.y,
r: gapSize / 2,
fill: that._containerBackgroundColor
});
return {
enabled: true,
_options: {offset: 0},
measure: function(layout) {
return {}
},
resize: function(layout) {
that._spindleOuter.applySettings({
cx: layout.x,
cy: layout.y
});
that._spindleInner.applySettings({
cx: layout.x,
cy: layout.y
});
return that
}
}
}
else {
that._spindle && that._spindle.remove();
delete that._spindle;
delete that._spindleOuter;
delete that._spindleInner;
return null
}
}
});
DX.viz.gauges.CircularGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.__internals.BaseGauge.prototype._factory);
DX.viz.gauges.CircularGauge.prototype._factory.createThemeManager = function() {
var themeManager = new DX.viz.gauges.__internals.ThemeManager;
themeManager._subTheme = '_circular';
return themeManager
}
})(DevExpress, jQuery);
/*! Module viz-gauges, file linearGauge.js */
(function(DX, $, undefined) {
var factory = DX.viz.gauges.__factory;
var _String = String,
_Number = Number,
max = Math.max,
min = Math.min,
round = Math.round,
slice = Array.prototype.slice,
$extend = $.extend,
$each = $.each;
DX.viz.gauges.LinearGauge = DX.viz.gauges.Gauge.inherit({
_rootClass: 'dxg-linear-gauge',
_selectMode: function() {
this.callBase.apply(this, arguments);
if (typeof this.indicatorValue === 'function')
this._createValueIndicatorInHardMode = function(type) {
return factory.createLinearValueIndicatorInHardMode(type)
}
},
_setupCodomain: function() {
var that = this,
geometry = that.option('geometry') || {},
vertical = _String(geometry.orientation).toLowerCase() === 'vertical';
that._area = {
vertical: vertical,
x: 0,
y: 0,
startCoord: -100,
endCoord: 100,
scaleSize: geometry.scaleSize > 0 ? _Number(geometry.scaleSize) : undefined
};
that._scale.vertical = vertical;
that._rangeContainer.vertical = vertical
},
_measureMainElements: function(elements) {
var that = this,
minBound = 1000,
maxBound = 0,
indent = 0;
$each(elements, function(_, element) {
var bounds = element.measure({
x: that._area.x + (_Number(element._options.offset) || 0),
y: that._area.y + (_Number(element._options.offset) || 0)
});
maxBound = max(maxBound, bounds.max);
minBound = min(minBound, bounds.min);
bounds.indent > 0 && (indent = max(indent, bounds.indent))
});
return {
minBound: minBound,
maxBound: maxBound,
indent: indent
}
},
_applyMainLayout: function(elements) {
var that = this,
measurements = that._measureMainElements(elements),
area = that._area,
rect,
offset,
counterSize = area.scaleSize + 2 * measurements.indent;
if (area.vertical) {
rect = that._layoutManager.selectRectBySizes({
width: measurements.maxBound - measurements.minBound,
height: counterSize
});
offset = rect.horizontalMiddle() - (measurements.minBound + measurements.maxBound) / 2;
area.startCoord = rect.bottom - measurements.indent;
area.endCoord = rect.top + measurements.indent;
area.x = round(area.x + offset)
}
else {
rect = that._layoutManager.selectRectBySizes({
height: measurements.maxBound - measurements.minBound,
width: counterSize
});
offset = rect.verticalMiddle() - (measurements.minBound + measurements.maxBound) / 2;
area.startCoord = rect.left + measurements.indent;
area.endCoord = rect.right - measurements.indent;
area.y = round(area.y + offset)
}
that._translator.setCodomain(area.startCoord, area.endCoord);
that._layoutManager.setRect(rect)
},
_updateElementPosition: function(element) {
element.resize({
x: round(this._area.x + (_Number(element._options.offset) || 0)),
y: round(this._area.y + (_Number(element._options.offset) || 0))
})
},
_createScale: function(parameters) {
return factory.createLinearScale(parameters)
},
_createRangeContainer: function(parameters) {
return factory.createLinearRangeContainer(parameters)
},
_createValueIndicator: function(type) {
return factory.createLinearValueIndicator(type)
},
_createSubvalueIndicator: function(type) {
return factory.createLinearSubvalueIndicator(type)
},
_getApproximateScreenRange: function() {
var that = this,
area = that._area,
s = area.vertical ? that._height : that._width;
s > area.totalSize && (s = area.totalSize);
s = s * 0.8;
return s
},
_getDefaultContainerSize: function() {
var geometry = this.option('geometry') || {};
if (geometry.orientation === 'vertical')
return {
width: 100,
height: 300
};
else
return {
width: 300,
height: 100
}
},
_getPreset: function() {
var preset = this.option('preset'),
result;
if (preset === 'preset2')
result = {
commonNeedleSettings: {type: 'rhombus'},
commonMarkerSettings: {type: 'triangle'}
};
else
result = {
commonNeedleSettings: {type: 'circle'},
commonMarkerSettings: {type: 'textcloud'}
};
return result
},
_createNeedle: function(type) {
return factory.createLinearNeedle(type)
},
_createMarker: function(type) {
return factory.createLinearMarker(type)
},
_createRangeBar: function() {
return factory.createLinearRangeBar()
}
});
DX.viz.gauges.LinearGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.__internals.BaseGauge.prototype._factory);
DX.viz.gauges.LinearGauge.prototype._factory.createThemeManager = function() {
var themeManager = new DX.viz.gauges.__internals.ThemeManager;
themeManager._subTheme = '_linear';
return themeManager
}
})(DevExpress, jQuery);
/*! Module viz-gauges, file barGauge.js */
(function(DX, $, undefined) {
var PI = Math.PI;
var _Number = window.Number,
_isFinite = window.isFinite,
_abs = Math.abs,
_round = Math.round,
_floor = Math.floor,
_min = Math.min,
_max = Math.max,
_isArray = DX.utils.isArray,
_convertAngleToRendererSpace = DX.utils.convertAngleToRendererSpace,
_getCosAndSin = DX.utils.getCosAndSin,
_noop = $.noop,
_extend = $.extend,
_getSampleText = DX.viz.gauges.__internals.getSampleText,
_formatValue = DX.viz.gauges.__internals.formatValue;
var _Rectangle = DX.viz.core.Rectangle,
_Palette = DX.viz.core.Palette;
DX.viz.gauges.BarGauge = DX.viz.gauges.__internals.BaseGauge.inherit({
_rootClass: 'dxbg-bar-gauge',
_init: function() {
var that = this;
that.callBase.apply(that, arguments);
that._barsGroup = that._renderer.createGroup({'class': 'dxbg-bars'});
that._values = [];
that._context = {
renderer: that._renderer,
translator: that._translator,
tracker: that._tracker,
group: that._barsGroup
};
that._animateStep = function(pos) {
var bars = that._bars,
i = 0,
ii = bars.length;
for (; i < ii; ++i)
bars[i].animate(pos)
};
that._animateComplete = function() {
var bars = that._bars,
i = 0,
ii = bars.length;
for (; i < ii; ++i)
bars[i].endAnimation()
}
},
_dispose: function() {
var that = this;
that.callBase.apply(that, arguments);
that._barsGroup = that._values = that._context = that._animateStep = that._animateComplete = null
},
_setupDomain: function() {
var that = this,
startValue = that.option('startValue'),
endValue = that.option('endValue');
_isFinite(startValue) || (startValue = 0);
_isFinite(endValue) || (endValue = 100);
that._translator.setDomain(startValue, endValue);
that._baseValue = that._translator.adjust(that.option('baseValue'));
_isFinite(that._baseValue) || (that._baseValue = startValue < endValue ? startValue : endValue)
},
_calculateSizeCore: function() {
var that = this,
size = that.option('size') || {};
if (_Number(size.width) === 0 || _Number(size.height) === 0) {
that._width = that._height = 0;
that._rootRect = new _Rectangle
}
else {
that._width = size.width > 0 ? _Number(size.width) : that._element().width() || 300;
that._height = size.height > 0 ? _Number(size.height) : that._element().height() || 300;
that._rootRect = new _Rectangle({
left: 0,
top: 0,
right: that._width,
bottom: that._height
})
}
},
_setupCodomain: DX.viz.gauges.CircularGauge.prototype._setupCodomain,
_getApproximateScreenRange: function() {
var that = this,
sides = that._area.sides,
width = that._width / (sides.right - sides.left),
height = that._height / (sides.down - sides.up),
r = width < height ? width : height;
return -that._translator.getCodomainRange() * r * PI / 180
},
_setupAnimationSettings: function() {
this.callBase();
if (this._animationSettings)
_extend(this._animationSettings, {
step: this._animateStep,
complete: this._animateComplete
})
},
_cleanContent: function() {
var that = this;
that._barsGroup.detach();
that._animationSettings && that._barsGroup.stopAnimation();
var i = 0,
ii = that._bars ? that._bars.length : 0;
for (; i < ii; ++i)
that._bars[i].dispose();
that._palette = that._bars = null
},
_renderContent: function() {
var that = this,
labelOptions = that.option('label');
that._barsGroup.append(that._root);
that._context.textEnabled = labelOptions === undefined || labelOptions && (!('visible' in labelOptions) || labelOptions.visible);
if (that._context.textEnabled) {
that._context.textColor = labelOptions && labelOptions.font && labelOptions.font.color || null;
labelOptions = _extend(true, {}, that._themeManager.theme().label, labelOptions);
that._context.formatOptions = {
format: labelOptions.format !== undefined || labelOptions.precision !== undefined ? labelOptions.format : that._defaultFormatOptions.format,
precision: labelOptions.format !== undefined || labelOptions.precision !== undefined ? labelOptions.precision : that._defaultFormatOptions.precision,
customizeText: labelOptions.customizeText
};
that._context.textOptions = {
font: _extend({}, that._themeManager.theme().label.font, labelOptions.font, {color: null}),
align: 'center'
};
that._textIndent = labelOptions.indent > 0 ? _Number(labelOptions.indent) : 0;
that._context.lineWidth = labelOptions.connectorWidth > 0 ? _Number(labelOptions.connectorWidth) : 0;
that._context.lineColor = labelOptions.connectorColor || null;
var text = that._renderer.createText(_getSampleText(that._translator, that._context.formatOptions), 0, 0, that._context.textOptions).append(that._barsGroup),
bbox = text.getBBox();
text.detach();
that._context.textVerticalOffset = -bbox.y - bbox.height / 2;
that._context.textWidth = bbox.width;
that._context.textHeight = bbox.height
}
DX.viz.gauges.CircularGauge.prototype._applyMainLayout.call(that);
that._renderBars()
},
_measureMainElements: function() {
var result = {maxRadius: this._area.radius};
if (this._context.textEnabled) {
result.horizontalMargin = this._context.textWidth;
result.verticalMargin = this._context.textHeight
}
return result
},
_renderBars: function() {
var that = this,
options = _extend({}, that._themeManager.theme(), that.option());
that._palette = new _Palette(options.palette, {
stepHighlight: 50,
theme: that._themeManager.themeName()
});
var relativeInnerRadius = options.relativeInnerRadius > 0 && options.relativeInnerRadius < 1 ? _Number(options.relativeInnerRadius) : 0.1,
radius = that._area.radius;
if (that._context.textEnabled) {
that._textIndent = _round(_min(that._textIndent, radius / 2));
radius -= that._textIndent
}
that._outerRadius = _round(radius);
that._innerRadius = _round(radius * relativeInnerRadius);
that._barSpacing = options.barSpacing > 0 ? _Number(options.barSpacing) : 0;
_extend(that._context, {
backgroundColor: options.backgroundColor,
x: that._area.x,
y: that._area.y,
startAngle: that._area.startCoord,
endAngle: that._area.endCoord,
baseAngle: that._translator.translate(that._baseValue)
});
that._bars = [];
that._updateValues(that.option('values'))
},
_arrangeBars: function(count) {
var that = this,
radius = that._outerRadius - that._innerRadius;
that._context.barSize = count > 0 ? _max((radius - (count - 1) * that._barSpacing) / count, 1) : 0;
var spacing = count > 1 ? _max(_min((radius - count * that._context.barSize) / (count - 1), that._barSpacing), 0) : 0,
_count = _min(_floor((radius + spacing) / that._context.barSize), count);
that._setBarsCount(_count);
radius = that._outerRadius;
that._context.textRadius = radius + that._textIndent;
that._palette.reset();
var unitOffset = that._context.barSize + spacing,
i = 0;
for (; i < _count; ++i, radius -= unitOffset)
that._bars[i].arrange({
radius: radius,
color: that._palette.getNextColor()
})
},
_setBarsCount: function(count) {
var that = this,
i,
ii;
if (that._bars.length > count) {
for (i = count, ii = that._bars.length; i < ii; ++i)
that._bars[i].dispose();
that._bars.splice(count, ii - count)
}
else if (that._bars.length < count)
for (i = that._bars.length, ii = count; i < ii; ++i)
that._bars.push(new BarWrapper(i, that._context));
if (that._bars.length > 0) {
if (that._dummyBackground) {
that._dummyBackground.detach();
that._dummyBackground = null
}
}
else {
if (!that._dummyBackground)
that._dummyBackground = that._renderer.createArc().append(that._barsGroup);
that._dummyBackground.applySettings({
x: that._context.x,
y: that._context.y,
outerRadius: that._outerRadius,
innerRadius: that._innerRadius,
startAngle: that._context.endAngle,
endAngle: that._context.startAngle,
fill: that._context.backgroundColor
})
}
},
_updateBars: function() {
var that = this,
i = 0,
ii = that._bars.length;
for (; i < ii; ++i)
that._bars[i].setValue(that._values[i])
},
_animateBars: function() {
var that = this,
i = 0,
ii = that._bars.length;
if (ii > 0) {
for (; i < ii; ++i)
that._bars[i].beginAnimation(that._values[i]);
that._barsGroup.animate({_: 0}, that._animationSettings)
}
},
_updateValues: function(values, noAnimation) {
var that = this,
list = _isArray(values) && values || _isFinite(values) && [values] || [],
i = 0,
ii = list.length,
value;
that._values = [];
for (; i < ii; ++i) {
value = that._translator.adjust(list[i]);
_isFinite(value) && that._values.push(value)
}
that._animationSettings && that._barsGroup.stopAnimation();
if (that._bars) {
that._arrangeBars(that._values.length);
if (that._animationSettings && !that._noAnimation)
that._animateBars();
else
that._updateBars()
}
if (!that._resizing) {
that.option('values', that._values);
that.hideLoadingIndicator()
}
},
values: function(arg) {
if (arg !== undefined) {
this._updateValues(arg);
return this
}
else
return this._values.slice(0)
},
_optionChanged: function(name, newValue, oldValue) {
switch (name) {
case'values':
this._updateValues(newValue);
break;
default:
this.callBase.apply(this, arguments);
break
}
},
_optionValuesEqual: function(name, oldValue, newValue) {
switch (name) {
case'values':
return compareArrays(oldValue, newValue);
default:
return this.callBase.apply(this, arguments)
}
}
});
var ThemeManager = DX.viz.gauges.__internals.ThemeManager.inherit({
_themeSection: 'barGauge',
_initializeTheme: function() {
var that = this;
that._initializeFont(that._theme.label.font);
that._initializeFont(that._theme.title.font);
that._initializeFont(that._theme.tooltip.font);
that._initializeFont(that._theme.loadingIndicator.font)
}
});
DX.viz.gauges.BarGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.__internals.BaseGauge.prototype._factory);
DX.viz.gauges.BarGauge.prototype._factory.createThemeManager = function() {
return new ThemeManager
};
function BarWrapper(index, context) {
var that = this;
that._context = context;
that._background = context.renderer.createArc().append(context.group);
that._background.applySettings({fill: context.backgroundColor});
that._bar = context.renderer.createArc().append(context.group);
if (context.textEnabled) {
that._line = context.renderer.createPath([], {strokeWidth: context.lineWidth}).append(context.group);
that._text = context.renderer.createText('', 0, 0, context.textOptions).append(context.group)
}
that._tracker = context.renderer.createArc();
context.tracker.attach(that._tracker, that, {index: index});
that._index = index;
that._angle = context.baseAngle;
that._settings = {
x: context.x,
y: context.y,
startAngle: context.baseAngle,
endAngle: context.baseAngle
}
}
_extend(BarWrapper.prototype, {
dispose: function() {
var that = this;
that._background.detach();
that._bar.detach();
if (that._context.textEnabled) {
that._line.detach();
that._text.detach()
}
that._context.tracker.detach(that._tracker);
that._context = that._settings = that._background = that._bar = that._line = that._text = that._tracker = null;
return that
},
arrange: function(options) {
var that = this;
that._settings.outerRadius = options.radius;
that._settings.innerRadius = options.radius - that._context.barSize;
that._background.applySettings(_extend({}, that._settings, {
startAngle: that._context.endAngle,
endAngle: that._context.startAngle
}));
that._bar.applySettings(that._settings);
that._tracker.applySettings(that._settings);
that._color = options.color;
that._bar.applySettings({fill: options.color});
if (that._context.textEnabled) {
that._line.applySettings({
points: [that._context.x, that._context.y - that._settings.innerRadius, that._context.x, that._context.y - that._context.textRadius],
stroke: that._context.lineColor || options.color
});
that._text.applySettings({font: {color: that._context.textColor || options.color}})
}
return that
},
getTooltipParameters: function() {
var that = this,
cossin = _getCosAndSin((that._angle + that._context.baseAngle) / 2);
return {
x: _round(that._context.x + (that._settings.outerRadius + that._settings.innerRadius) / 2 * cossin.cos),
y: _round(that._context.y - (that._settings.outerRadius + that._settings.innerRadius) / 2 * cossin.sin),
offset: 0,
color: that._color,
value: that._value
}
},
setAngle: function(angle) {
var that = this;
that._angle = angle;
setAngles(that._settings, that._context.baseAngle, that._angle);
that._bar.applySettings(that._settings);
that._tracker.applySettings(that._settings);
if (that._context.textEnabled) {
that._line.rotate(_convertAngleToRendererSpace(that._angle), that._context.x, that._context.y);
var cossin = _getCosAndSin(that._angle);
that._text.applySettings({
text: _formatValue(that._value, that._context.formatOptions, {index: that._index}),
x: that._context.x + (that._context.textRadius + that._context.textWidth * 0.6) * cossin.cos,
y: that._context.y - (that._context.textRadius + that._context.textHeight * 0.6) * cossin.sin + that._context.textVerticalOffset
})
}
return that
},
setValue: function(value) {
this._value = value;
return this.setAngle(this._context.translator.translate(value))
},
beginAnimation: function(value) {
var that = this;
that._value = value;
var angle = that._context.translator.translate(value);
if (!compareFloats(that._angle, angle)) {
that._start = that._angle;
that._delta = angle - that._angle;
that._tracker.applySettings({visibility: 'hidden'});
if (that._context.textEnabled) {
that._line.applySettings({visibility: 'hidden'});
that._text.applySettings({visibility: 'hidden'})
}
}
else
that.animate = _noop
},
animate: function(pos) {
var that = this;
that._angle = that._start + that._delta * pos;
setAngles(that._settings, that._context.baseAngle, that._angle);
that._bar.applySettings(that._settings)
},
endAnimation: function() {
var that = this;
if (that._delta !== undefined) {
if (compareFloats(that._angle, that._start + that._delta)) {
that._tracker.applySettings({visibility: null});
if (that._context.textEnabled) {
that._line.applySettings({visibility: null});
that._text.applySettings({visibility: null})
}
that.setAngle(that._angle)
}
}
else
delete that.animate;
delete that._start;
delete that._delta
}
});
function setAngles(target, angle1, angle2) {
target.startAngle = angle1 < angle2 ? angle1 : angle2;
target.endAngle = angle1 < angle2 ? angle2 : angle1
}
function compareFloats(value1, value2) {
return _abs(value1 - value2) < 0.0001
}
function compareArrays(array1, array2) {
if (array1 === array2)
return true;
if (_isArray(array1) && _isArray(array2) && array1.length === array2.length) {
for (var i = 0, ii = array1.length; i < ii; ++i)
if (!compareFloats(array1[i], array2[i]))
return false;
return true
}
return false
}
var __BarWrapper = BarWrapper;
DX.viz.gauges.__tests.BarWrapper = __BarWrapper;
DX.viz.gauges.__tests.stubBarWrapper = function(barWrapperType) {
BarWrapper = barWrapperType
};
DX.viz.gauges.__tests.restoreBarWrapper = function() {
BarWrapper = __BarWrapper
};
DX.registerComponent('dxBarGauge', DX.viz.gauges.BarGauge)
})(DevExpress, jQuery);
/*! Module viz-gauges, file tracker.js */
(function(DX, $, undefined) {
var _setTimeout = window.setTimeout,
_clearTimeout = window.clearTimeout,
_extend = $.extend,
_abs = Math.abs;
var TOOLTIP_SHOW_DELAY = 300,
TOOLTIP_HIDE_DELAY = 300,
TOOLTIP_TOUCH_SHOW_DELAY = 400,
TOOLTIP_TOUCH_HIDE_DELAY = 300;
DX.viz.gauges.__internals.Tracker = DX.Class.inherit({
ctor: function(parameters) {
DX.utils.debug.assertParam(parameters, 'parameters');
DX.utils.debug.assertParam(parameters.renderer, 'parameters.renderer');
DX.utils.debug.assertParam(parameters.container, 'parameters.container');
var that = this;
that._container = parameters.container;
that._element = parameters.renderer.createGroup({
'class': 'dxg-tracker',
stroke: 'none',
strokeWidth: 0,
fill: '#000000',
opacity: 0.0001
});
that._showTooltipCallback = function() {
that._showTooltipTimeout = null;
var target = that._tooltipEvent.target;
that._targetEvent = null;
if (that._tooltipTarget !== target) {
that._tooltipTarget = target;
that._callbacks['tooltip-show']()
}
};
that._hideTooltipCallback = function() {
that._hideTooltipTimeout = null;
that._targetEvent = null;
if (that._tooltipTarget) {
that._callbacks['tooltip-hide']();
that._tooltipTarget = null
}
};
that._dispose = function() {
that._showTooltipCallback = that._hideTooltipCallback = that._dispose = null
};
that._DEBUG_showTooltipTimeoutSet = that._DEBUG_showTooltipTimeoutCleared = that._DEBUG_hideTooltipTimeoutSet = that._DEBUG_hideTooltipTimeoutCleared = 0
},
dispose: function() {
var that = this;
that._dispose();
that.deactivate();
that._element.off();
that._container = that._element = that._context = that._callbacks = null;
return that
},
activate: function() {
this._element.append(this._container);
return this
},
deactivate: function() {
this._element.detach();
this._element.clear();
return this
},
attach: function(element, target, info) {
element.data({
target: target,
info: info
});
element.append(this._element);
return this
},
detach: function(element) {
element.detach();
element.removeData();
return this
},
setTooltipState: function(state) {
var that = this,
data;
that._element.off(tooltipMouseEvents).off(tooltipTouchEvents);
if (state) {
data = {tracker: that};
that._element.on(tooltipMouseEvents, data).on(tooltipTouchEvents, data)
}
return that
},
setCallbacks: function(callbacks) {
this._callbacks = callbacks;
return this
},
_showTooltip: function(event, delay) {
var that = this,
data = $(event.target).data();
if (that._tooltipTarget === event.target || that._callbacks['tooltip-prepare'](data.target, data.info)) {
that._hideTooltipTimeout && ++that._DEBUG_hideTooltipTimeoutCleared;
_clearTimeout(that._hideTooltipTimeout);
that._hideTooltipTimeout = null;
_clearTimeout(that._showTooltipTimeout);
that._tooltipEvent = event;
++that._DEBUG_showTooltipTimeoutSet;
that._showTooltipTimeout = _setTimeout(that._showTooltipCallback, delay)
}
},
_hideTooltip: function(delay) {
var that = this;
that._showTooltipTimeout && ++that._DEBUG_showTooltipTimeoutCleared;
_clearTimeout(that._showTooltipTimeout);
that._showTooltipTimeout = null;
_clearTimeout(that._hideTooltipTimeout);
++that._DEBUG_hideTooltipTimeoutSet;
that._hideTooltipTimeout = _setTimeout(that._hideTooltipCallback, delay)
}
});
var tooltipMouseEvents = {
'mouseover.gauge-tooltip': handleTooltipMouseOver,
'mouseout.gauge-tooltip': handleTooltipMouseOut
};
var tooltipMouseMoveEvents = {'mousemove.gauge-tooltip': handleTooltipMouseMove};
var tooltipTouchEvents = {'touchstart.gauge-tooltip': handleTooltipTouchStart};
function handleTooltipMouseOver(event) {
var tracker = event.data.tracker;
tracker._x = event.pageX;
tracker._y = event.pageY;
tracker._element.off(tooltipMouseMoveEvents).on(tooltipMouseMoveEvents, event.data);
tracker._showTooltip(event, TOOLTIP_SHOW_DELAY)
}
function handleTooltipMouseMove(event) {
var tracker = event.data.tracker;
if (tracker._showTooltipTimeout && _abs(event.pageX - tracker._x) > 4 || _abs(event.pageY - tracker._y) > 4) {
tracker._x = event.pageX;
tracker._y = event.pageY;
tracker._showTooltip(event, TOOLTIP_SHOW_DELAY)
}
}
function handleTooltipMouseOut(event) {
var tracker = event.data.tracker;
tracker._element.off(tooltipMouseMoveEvents);
tracker._hideTooltip(TOOLTIP_HIDE_DELAY)
}
var active_touch_tooltip_tracker = null;
DX.viz.gauges.__internals.Tracker._DEBUG_reset = function() {
active_touch_tooltip_tracker = null
};
function handleTooltipTouchStart(event) {
event.preventDefault();
var tracker = active_touch_tooltip_tracker;
if (tracker && tracker !== event.data.tracker)
tracker._hideTooltip(TOOLTIP_TOUCH_HIDE_DELAY);
tracker = active_touch_tooltip_tracker = event.data.tracker;
tracker._showTooltip(event, TOOLTIP_TOUCH_SHOW_DELAY);
tracker._touch = true
}
function handleTooltipDocumentTouchStart(event) {
var tracker = active_touch_tooltip_tracker;
if (tracker) {
if (!tracker._touch) {
tracker._hideTooltip(TOOLTIP_TOUCH_HIDE_DELAY);
active_touch_tooltip_tracker = null
}
tracker._touch = null
}
}
function handleTooltipDocumentTouchEnd(event) {
var tracker = active_touch_tooltip_tracker;
if (tracker)
if (tracker._showTooltipTimeout) {
tracker._hideTooltip(TOOLTIP_TOUCH_HIDE_DELAY);
active_touch_tooltip_tracker = null
}
}
$(window.document).on({
'touchstart.gauge-tooltip': handleTooltipDocumentTouchStart,
'touchend.gauge-tooltip': handleTooltipDocumentTouchEnd
})
})(DevExpress, jQuery);
/*! Module viz-gauges, file dxCircularGauge.js */
(function(DX, undefined) {
DX.registerComponent("dxCircularGauge", DX.viz.gauges.CircularGauge)
})(DevExpress);
/*! Module viz-gauges, file dxLinearGauge.js */
(function(DX, undefined) {
DX.registerComponent("dxLinearGauge", DX.viz.gauges.LinearGauge)
})(DevExpress);
DevExpress.MOD_VIZ_GAUGES = true
}
if (!DevExpress.MOD_VIZ_RANGESELECTOR) {
if (!DevExpress.MOD_VIZ_CORE)
throw Error('Required module is not referenced: viz-core');
/*! Module viz-rangeselector, file namespaces.js */
(function(DevExpress) {
DevExpress.viz.rangeSelector = {utils: {}}
})(DevExpress);
/*! Module viz-rangeselector, file utils.js */
(function($, DX, undefined) {
var rangeSelector = DX.viz.rangeSelector,
utils = rangeSelector.utils,
dxUtils = DX.utils;
var INVISIBLE_POS = -1000;
var findLessOrEqualValueIndex = function(values, value) {
if (!values || values.length === 0)
return -1;
var minIndex = 0,
maxIndex = values.length - 1,
index = 0;
while (maxIndex - minIndex > 1) {
var index = minIndex + maxIndex >> 1;
if (values[index] > value)
maxIndex = index;
else
minIndex = index
}
return values[maxIndex] <= value ? maxIndex : minIndex
};
var findLessOrEqualValue = function(values, value) {
var index = findLessOrEqualValueIndex(values, value);
if (values && index >= 0 && index < values.length)
return values[index];
return value
};
var findNearValue = function(values, value) {
var index = findLessOrEqualValueIndex(values, value);
if (values && index >= 0 && index < values.length) {
if (index + 1 < values.length)
if (dxUtils.isDate(value)) {
if (values[index + 1].getTime() - value.getTime() < value.getTime() - values[index].getTime())
index++
}
else if (values[index + 1] - value < value - values[index])
index++;
return values[index]
}
return value
};
var findGreaterOrEqualValue = function(values, value) {
var index = findLessOrEqualValueIndex(values, value);
if (values && index >= 0 && index < values.length) {
if (values[index] < value && index + 1 < values.length)
index++;
return values[index]
}
return value
};
var getInterval = function(valueMin, valueMax, delta) {
var result,
minDateDaysCount,
maxDateDaysCount,
daysCount,
prevMaxDaysCount;
if (dxUtils.isDate(valueMin)) {
if (delta === 'year' || delta === 'quarter' || delta === 'month')
return {months: valueMax.getFullYear() * 12 + valueMax.getMonth() - valueMin.getFullYear() * 12 - valueMin.getMonth()};
else
return {milliseconds: valueMax.valueOf() - valueMin.valueOf()};
return result
}
else
return valueMax - valueMin
};
var getRootOffsetLeft = function(renderer) {
return dxUtils.getRootOffset(renderer).left || 0
};
var getEventPageX = function(eventArgs) {
var result = 0;
if (eventArgs.pageX)
result = eventArgs.pageX;
else if (eventArgs.originalEvent && eventArgs.originalEvent.pageX)
result = eventArgs.originalEvent.pageX;
if (eventArgs.originalEvent && eventArgs.originalEvent.touches)
if (eventArgs.originalEvent.touches.length > 0)
result = eventArgs.originalEvent.touches[0].pageX;
else if (eventArgs.originalEvent.changedTouches.length > 0)
result = eventArgs.originalEvent.changedTouches[0].pageX;
return result
};
var getTextBBox = function(renderer, text, fontOptions) {
var textElement = renderer.createText(text, INVISIBLE_POS, INVISIBLE_POS, {font: fontOptions}).append();
var textBBox = textElement.getBBox();
textElement.remove();
return textBBox
};
utils.findLessOrEqualValue = findLessOrEqualValue;
utils.findNearValue = findNearValue;
utils.findGreaterOrEqualValue = findGreaterOrEqualValue;
utils.getInterval = getInterval;
utils.getRootOffsetLeft = getRootOffsetLeft;
utils.getEventPageX = getEventPageX;
utils.getTextBBox = getTextBBox
})(jQuery, DevExpress);
/*! Module viz-rangeselector, file baseVisualElement.js */
(function(DX) {
DevExpress.viz.rangeSelector.BaseVisualElement = DX.Class.inherit({
ctor: function(renderer) {
this._renderer = renderer;
this._isDrawn = false
},
applyOptions: function(options) {
this._options = options || {};
this._applyOptions(this._options)
},
_applyOptions: function(options){},
redraw: function(group) {
var that = this;
if (!that._isDrawn) {
that._isDrawn = !(that._draw(group || that._group) === false);
if (group)
that._group = group
}
else
that._update(group || that._group)
},
isDrawn: function() {
return !!this._isDrawn
},
isInitialized: function() {
return !!this._options
},
_draw: function(group){},
_update: function(group) {
group.clear();
this._draw(group)
}
})
})(DevExpress);
/*! Module viz-rangeselector, file rangeSelector.js */
(function($, DX, undefined) {
var rangeSelector = DX.viz.rangeSelector,
utils = DX.utils,
dataUtils = DX.data.utils,
rangeSelectorUtils = rangeSelector.utils,
ParseUtils = DX.viz.core.ParseUtils,
formatHelper = DX.formatHelper,
core = DX.viz.core,
_max = Math.max,
_isDefined = utils.isDefined;
rangeSelector.consts = {
fontHeightRatio: 0.55,
emptySliderMarkerText: '. . .'
};
rangeSelector.formatValue = function(value, formatOptions) {
var formatObject = {
value: value,
valueText: formatHelper.format(value, formatOptions.format, formatOptions.precision)
};
return String(utils.isFunction(formatOptions.customizeText) ? formatOptions.customizeText.call(formatObject, formatObject) : formatObject.valueText)
};
rangeSelector.RangeSelector = core.BaseWidget.inherit(function() {
var SCALE_TEXT_SPACING = 5;
var defaultRangeSelectorOptions = {
size: undefined,
margin: {
left: 0,
top: 0,
right: 0,
bottom: 0
},
scale: {
showCustomBoundaryTicks: true,
showMinorTicks: true,
startValue: undefined,
endValue: undefined,
minorTickCount: undefined,
minorTickInterval: undefined,
majorTickInterval: undefined,
useTicksAutoArrangement: true,
setTicksAtUnitBeginning: true,
minRange: undefined,
maxRange: undefined,
placeholderHeight: undefined,
valueType: undefined,
label: {
visible: true,
format: undefined,
precision: undefined,
customizeText: undefined
},
marker: {
visible: true,
label: {
format: undefined,
precision: undefined,
customizeText: undefined
}
},
logarithmBase: 10
},
selectedRange: undefined,
sliderMarker: {
visible: true,
format: undefined,
precision: undefined,
customizeText: undefined,
placeholderSize: undefined
},
behavior: {
snapToTicks: true,
animationEnabled: true,
moveSelectedRangeByClick: true,
manualRangeSelectionEnabled: true,
allowSlidersSwap: true,
callSelectedRangeChanged: "onMovingComplete"
},
background: {
color: "#C0BAE1",
visible: true,
image: {
url: undefined,
location: 'full'
}
},
dataSource: undefined,
dataSourceField: 'arg',
redrawOnResize: true,
theme: undefined,
selectedRangeChanged: null
};
var calculateMarkerSize = function(renderer, value, sliderMarkerOptions) {
var formattedText = value === undefined ? rangeSelector.consts.emptySliderMarkerText : rangeSelector.formatValue(value, sliderMarkerOptions),
textBBox = rangeSelectorUtils.getTextBBox(renderer, formattedText, sliderMarkerOptions.font);
return {
width: Math.ceil(textBBox.width) + 2 * sliderMarkerOptions.padding,
height: Math.ceil(textBBox.height * rangeSelector.consts.fontHeightRatio) + 2 * sliderMarkerOptions.padding + sliderMarkerOptions.pointerSize
}
};
var calculateScaleLabelHalfWidth = function(renderer, value, scaleOptions) {
var formattedText = rangeSelector.formatValue(value, scaleOptions.label),
textBBox = rangeSelectorUtils.getTextBBox(renderer, formattedText, scaleOptions.label.font);
return Math.ceil(textBBox.width / 2)
};
var calculateRangeContainerCanvas = function(size, margin, sliderMarkerSpacing) {
var canvas = {
left: margin.left + sliderMarkerSpacing.left,
top: margin.top + sliderMarkerSpacing.top,
width: size.width - margin.left - margin.right - sliderMarkerSpacing.left - sliderMarkerSpacing.right,
height: size.height - margin.top - margin.bottom - sliderMarkerSpacing.top - sliderMarkerSpacing.bottom
};
if (canvas.width <= 0)
canvas.width = 1;
return canvas
};
var parseSliderMarkersPlaceholderSize = function(placeholderSize) {
var placeholderWidthLeft,
placeholderWidthRight,
placeholderHeight;
if (utils.isNumber(placeholderSize))
placeholderWidthLeft = placeholderWidthRight = placeholderHeight = placeholderSize;
else if (placeholderSize) {
if (utils.isNumber(placeholderSize.height))
placeholderHeight = placeholderSize.height;
if (utils.isNumber(placeholderSize.width))
placeholderWidthLeft = placeholderWidthRight = placeholderSize.width;
else if (placeholderSize.width) {
if (utils.isNumber(placeholderSize.width.left))
placeholderWidthLeft = placeholderSize.width.left;
if (utils.isNumber(placeholderSize.width.right))
placeholderWidthRight = placeholderSize.width.right
}
}
return {
widthLeft: placeholderWidthLeft,
widthRight: placeholderWidthRight,
height: placeholderHeight
}
};
var calculateSliderMarkersSpacing = function(renderer, size, scale, sliderMarkerOptions) {
var leftMarkerSize,
leftScaleLabelWidth = 0,
rightScaleLabelWidth = 0,
rightMarkerSize,
placeholderWidthLeft = 0,
placeholderWidthRight = 0,
placeholderHeight = 0,
parsedPlaceholderSize,
markerMaxWidth;
parsedPlaceholderSize = parseSliderMarkersPlaceholderSize(sliderMarkerOptions.placeholderSize);
placeholderWidthLeft = parsedPlaceholderSize.widthLeft || 0;
placeholderWidthRight = parsedPlaceholderSize.widthRight || 0;
placeholderHeight = parsedPlaceholderSize.height || 0;
if (sliderMarkerOptions.visible) {
leftMarkerSize = calculateMarkerSize(renderer, scale.startValue, sliderMarkerOptions);
rightMarkerSize = calculateMarkerSize(renderer, scale.endValue, sliderMarkerOptions);
markerMaxWidth = _max(leftMarkerSize.width, rightMarkerSize.width);
if (!placeholderWidthLeft)
placeholderWidthLeft = markerMaxWidth;
if (!placeholderWidthRight)
placeholderWidthRight = markerMaxWidth;
if (!placeholderHeight)
placeholderHeight = _max(leftMarkerSize.height, rightMarkerSize.height)
}
if (scale.label.visible) {
leftScaleLabelWidth = calculateScaleLabelHalfWidth(renderer, scale.startValue, scale);
rightScaleLabelWidth = calculateScaleLabelHalfWidth(renderer, scale.endValue, scale)
}
placeholderWidthLeft = _max(placeholderWidthLeft, leftScaleLabelWidth);
placeholderWidthRight = _max(placeholderWidthRight, rightScaleLabelWidth);
return {
left: placeholderWidthLeft,
right: placeholderWidthRight,
top: placeholderHeight,
bottom: 0
}
};
var clearContainer = function(container) {
if (container)
container.empty()
};
var getContainer = function(that) {
return that._element()
};
var createRangeContainer = function(rangeContainerOptions) {
return rangeSelector.rangeSelectorFactory.createRangeContainer(rangeContainerOptions)
};
var createTranslator = function(range, canvas) {
return {
x: core.CoreFactory.createTranslator2D(range.arg, canvas, {direction: "horizontal"}),
y: core.CoreFactory.createTranslator2D(range.val, canvas)
}
};
var createTranslatorCanvas = function(sizeOptions, rangeContainerCanvas, scaleLabelsAreaHeight) {
return {
left: rangeContainerCanvas.left,
top: rangeContainerCanvas.top,
right: sizeOptions.width - rangeContainerCanvas.width - rangeContainerCanvas.left,
bottom: sizeOptions.height - rangeContainerCanvas.height - rangeContainerCanvas.top + scaleLabelsAreaHeight,
width: sizeOptions.width,
height: sizeOptions.height
}
};
var createRenderer = function(that) {
var renderer = that.option('renderer');
if (renderer)
return renderer;
return core.CoreFactory.createRenderer({
pathModified: that.option('pathModified'),
rtl: that.option('rtlEnabled')
})
};
var createThemeManager = function(theme) {
return rangeSelector.rangeSelectorFactory.createThemeManager(theme)
};
var calculateValueType = function(firstValue, secondValue) {
var types = [$.type(firstValue), $.type(secondValue)];
$.inArray();
return $.inArray('date', types) != -1 ? 'datetime' : $.inArray('number', types) != -1 ? 'numeric' : ''
};
var createSeriesDataSource = function(that) {
var seriesDataSource,
dataSource = that._dataSource && that._dataSource.items(),
scaleOptions = that.option('scale'),
chartOptions = that.option('chart') || {},
valueType = scaleOptions.valueType;
if (!valueType)
valueType = calculateValueType(scaleOptions.startValue, scaleOptions.endValue);
if (dataSource || chartOptions.series) {
seriesDataSource = new rangeSelector.SeriesDataSource({
renderer: that.renderer,
dataSource: dataSource,
valueType: (valueType || '').toLowerCase(),
axisType: scaleOptions.type,
chart: chartOptions,
dataSourceField: that.option('dataSourceField'),
backgroundColor: that._userBackgroundColor,
incidentOccured: that._incidentOccured
});
checkLogarithmicOptions(chartOptions.valueAxis, seriesDataSource.themeManager.theme().valueAxis.logarithmBase, that._incidentOccured)
}
return seriesDataSource
};
var calculateTranslatorRange = function(that, seriesDataSource, scaleOptions) {
var translatorRange,
minValue,
maxValue,
inverted = false,
isEqualDates;
if (_isDefined(scaleOptions.startValue) && _isDefined(scaleOptions.endValue)) {
inverted = scaleOptions.inverted = scaleOptions.startValue > scaleOptions.endValue;
minValue = inverted ? scaleOptions.endValue : scaleOptions.startValue;
maxValue = inverted ? scaleOptions.startValue : scaleOptions.endValue
}
else if (_isDefined(scaleOptions.startValue) || _isDefined(scaleOptions.endValue)) {
minValue = scaleOptions.startValue;
maxValue = scaleOptions.endValue
}
translatorRange = seriesDataSource ? seriesDataSource.getBoundRange() : {
arg: new core.Range,
val: new core.Range({isValueRange: true})
};
isEqualDates = utils.isDate(minValue) && utils.isDate(maxValue) && minValue.getTime() === maxValue.getTime();
if (minValue !== maxValue && !isEqualDates)
translatorRange.arg.addRange({
invert: inverted,
min: minValue,
max: maxValue,
minVisible: minValue,
maxVisible: maxValue,
dataType: scaleOptions.valueType
});
translatorRange.arg.addRange({
base: scaleOptions.logarithmBase,
axisType: scaleOptions.type
});
if (!translatorRange.arg.isDefined()) {
if (isEqualDates)
scaleOptions.valueType = 'numeric';
translatorRange.arg.setStubData(scaleOptions.valueType)
}
return translatorRange
};
var calculateScaleAreaHeight = function(renderer, scaleOptions, visibleMarkers) {
var textBBox,
visibleLabels = scaleOptions.label.visible;
if (scaleOptions.placeholderHeight)
return scaleOptions.placeholderHeight;
else {
textBBox = rangeSelectorUtils.getTextBBox(renderer, '0', scaleOptions.label.font);
return (visibleLabels ? scaleOptions.label.topIndent + textBBox.height : 0) + (visibleMarkers ? scaleOptions.marker.topIndent + scaleOptions.marker.separatorHeight : 0)
}
};
var getTicksInfo = function(that, scaleOptions, translators, screenDelta) {
var isEmpty = scaleOptions.isEmpty,
tickProvider = core.CoreFactory.getTickProvider(),
minorTicksOptions,
majorTicksOptions,
startValue,
endValue,
businessRange = translators.x.getBusinessRange();
minorTicksOptions = {
tickInterval: isEmpty ? 0 : that.option('scale').minorTickInterval,
showCustomBoundaryTicks: scaleOptions.showCustomBoundaryTicks,
minorTickCount: scaleOptions.minorTickCount
};
majorTicksOptions = {
textOptions: {
align: 'center',
font: scaleOptions.label.font
},
renderer: that.renderer,
getText: function(value) {
return rangeSelector.formatValue(value, scaleOptions.label)
},
translator: translators.x,
isStartTickGenerated: !_isDefined(that.option('scale').majorTickInterval),
tickInterval: scaleOptions.majorTickInterval,
textSpacing: SCALE_TEXT_SPACING,
setTicksAtUnitBeginning: scaleOptions.setTicksAtUnitBeginning,
useTicksAutoArrangement: scaleOptions.useTicksAutoArrangement,
hideLabels: isEmpty
};
startValue = isEmpty ? businessRange.min : scaleOptions.startValue;
endValue = isEmpty ? businessRange.max : scaleOptions.endValue;
return tickProvider.getFullTicks(startValue, endValue, screenDelta, majorTicksOptions, minorTicksOptions, {
axisType: scaleOptions.type,
dataType: scaleOptions.valueType,
base: scaleOptions.logarithmBase
})
};
var updateTickIntervals = function(scaleOptions, screenDelta, incidentOccured) {
var tickProvider = core.CoreFactory.getTickProvider(),
tickIntervals = tickProvider.getTickIntervals(scaleOptions.startValue, scaleOptions.endValue, screenDelta, {
tickInterval: scaleOptions.majorTickInterval,
incidentOccured: incidentOccured
}, {
tickInterval: scaleOptions.minorTickInterval,
incidentOccured: incidentOccured
}, {
axisType: scaleOptions.type,
dataType: scaleOptions.valueType,
base: scaleOptions.logarithmBase
});
scaleOptions.minorTickInterval = tickIntervals.minorTickInterval;
scaleOptions.majorTickInterval = tickIntervals.majorTickInterval
};
var updateScaleOptions = function(that, seriesDataSource, translatorRange, screenDelta, scaleOptions) {
var minVisibleX = _isDefined(translatorRange.arg.minVisible) ? translatorRange.arg.minVisible : translatorRange.arg.min,
maxVisibleX = _isDefined(translatorRange.arg.maxVisible) ? translatorRange.arg.maxVisible : translatorRange.arg.max,
isEmptyInterval;
if (seriesDataSource && !seriesDataSource.isEmpty()) {
scaleOptions.startValue = scaleOptions.inverted ? maxVisibleX : minVisibleX;
scaleOptions.endValue = scaleOptions.inverted ? minVisibleX : maxVisibleX
}
isEmptyInterval = utils.isDate(scaleOptions.startValue) && utils.isDate(scaleOptions.endValue) && scaleOptions.startValue.getTime() === scaleOptions.endValue.getTime() || scaleOptions.startValue === scaleOptions.endValue;
scaleOptions.isEmpty = !_isDefined(scaleOptions.startValue) || !_isDefined(scaleOptions.endValue) || isEmptyInterval || scaleOptions.valueType === 'string';
if (scaleOptions.isEmpty)
scaleOptions.startValue = scaleOptions.endValue = undefined;
else {
updateTickIntervals(scaleOptions, screenDelta, that._incidentOccured);
if (scaleOptions.valueType === 'datetime' && !_isDefined(scaleOptions.label.format))
if (!scaleOptions.marker.visible)
scaleOptions.label.format = formatHelper.getDateFormatByTickInterval(scaleOptions.startValue, scaleOptions.endValue, scaleOptions.majorTickInterval);
else
scaleOptions.label.format = utils.getDateUnitInterval(scaleOptions.majorTickInterval)
}
};
var prepareSliderMarkersOptions = function(that, scaleOptions, screenDelta) {
var sliderMarkerOptions = $.extend(true, {}, that.option('sliderMarker')),
businessInterval;
if (!sliderMarkerOptions.format) {
if (!that.option('behavior').snapToTicks && utils.isNumber(scaleOptions.startValue)) {
businessInterval = Math.abs(scaleOptions.endValue - scaleOptions.startValue);
sliderMarkerOptions.format = 'fixedPoint';
sliderMarkerOptions.precision = utils.getSignificantDigitPosition(businessInterval / screenDelta)
}
if (scaleOptions.valueType === 'datetime')
if (!scaleOptions.marker.visible) {
if (_isDefined(scaleOptions.startValue) && _isDefined(scaleOptions.endValue))
sliderMarkerOptions.format = formatHelper.getDateFormatByTickInterval(scaleOptions.startValue, scaleOptions.endValue, scaleOptions.minorTickInterval !== 0 ? scaleOptions.minorTickInterval : scaleOptions.majorTickInterval)
}
else
sliderMarkerOptions.format = utils.getDateUnitInterval(_isDefined(scaleOptions.minorTickInterval) && scaleOptions.minorTickInterval !== 0 ? scaleOptions.minorTickInterval : scaleOptions.majorTickInterval)
}
return sliderMarkerOptions
};
var showScaleMarkers = function(scaleOptions) {
return scaleOptions.valueType == 'datetime' && scaleOptions.marker.visible
};
var updateTranslatorRangeInterval = function(translatorRange, scaleOptions) {
var intervalX = scaleOptions.minorTickInterval || scaleOptions.majorTickInterval;
translatorRange = translatorRange.arg.addRange({interval: intervalX})
};
var checkLogarithmicOptions = function(options, logarithmBase, incidentOccured) {
if (!options)
return;
if (options.type === 'logarithmic' && options.logarithmBase <= 0 || options.logarithmBase && !$.isNumeric(options.logarithmBase)) {
options.logarithmBase = logarithmBase;
incidentOccured('E2104')
}
else if (options.type !== 'logarithmic')
options.logarithmBase = undefined
};
var prepareScaleOptions = function(that, seriesDataSource) {
var scaleOptions = $.extend(true, {}, that.option('scale')),
incidentOccured = that._incidentOccured,
parsedValue = 0,
parseUtils = new ParseUtils({incidentOccured: incidentOccured}),
valueType = parseUtils.correctValueType((scaleOptions.valueType || '').toLowerCase());
if (seriesDataSource)
valueType = seriesDataSource.getCalculatedValueType() || valueType;
if (!valueType)
valueType = calculateValueType(scaleOptions.startValue, scaleOptions.endValue) || 'numeric';
scaleOptions.valueType = valueType;
if (scaleOptions.valueType === 'string') {
that._incidentOccured("E2201");
return scaleOptions
}
var parser = parseUtils.getParser(valueType, 'scale');
if (_isDefined(scaleOptions.startValue)) {
parsedValue = parser(scaleOptions.startValue);
if (_isDefined(parsedValue))
scaleOptions.startValue = parsedValue;
else {
scaleOptions.startValue = undefined;
that._incidentOccured("E2202", ["start"])
}
}
if (_isDefined(scaleOptions.endValue)) {
parsedValue = parser(scaleOptions.endValue);
if (_isDefined(parsedValue))
scaleOptions.endValue = parsedValue;
else {
scaleOptions.endValue = undefined;
that._incidentOccured("E2202", ["end"])
}
}
checkLogarithmicOptions(scaleOptions, defaultRangeSelectorOptions.scale.logarithmBase, that._incidentOccured);
if (!scaleOptions.type)
scaleOptions.type = 'continuous';
scaleOptions.parser = parser;
return scaleOptions
};
var correctSizeOptions = function(that, sizeOptions, scaleOptions) {
var size = that.option('size') || {};
if (!sizeOptions.height && size.height !== 0)
if (scaleOptions.valueType === 'datetime' && scaleOptions.marker.visible !== false)
sizeOptions.height = 160;
else
sizeOptions.height = 120;
if (!sizeOptions.width && size.width !== 0)
sizeOptions.width = 400
};
var applyOptions = function(that) {
var rangeContainerCanvas,
seriesDataSource,
translatorRange,
scaleLabelsAreaHeight,
sizeOptions,
sliderMarkerSpacing,
sliderMarkerOptions,
selectedRange,
$container = that.container;
that._isUpdating = true;
sizeOptions = calculateSize(that);
that._actualSize = sizeOptions;
seriesDataSource = createSeriesDataSource(that);
that._scaleOptions = prepareScaleOptions(that, seriesDataSource);
correctSizeOptions(that, sizeOptions, that._scaleOptions);
if (!sizeOptions.width || !sizeOptions.height || !$container.is(':visible')) {
that.stopRedraw = true;
that._incidentOccured("W2001", [that.NAME]);
return
}
else
that.stopRedraw = false;
updateRendererSize(that, sizeOptions);
that._updateLoadIndicator(undefined, that.canvas.width, that.canvas.height);
translatorRange = calculateTranslatorRange(that, seriesDataSource, that._scaleOptions);
updateScaleOptions(that, seriesDataSource, translatorRange, sizeOptions.width, that._scaleOptions);
updateTranslatorRangeInterval(translatorRange, that._scaleOptions);
sliderMarkerOptions = prepareSliderMarkersOptions(that, that._scaleOptions, sizeOptions.width);
selectedRange = initSelection(that, that._scaleOptions);
sliderMarkerSpacing = calculateSliderMarkersSpacing(that.renderer, sizeOptions, that._scaleOptions, sliderMarkerOptions);
rangeContainerCanvas = calculateRangeContainerCanvas(sizeOptions, that.option('margin'), sliderMarkerSpacing);
scaleLabelsAreaHeight = calculateScaleAreaHeight(that.renderer, that._scaleOptions, showScaleMarkers(that._scaleOptions));
that.translators = createTranslator(translatorRange, createTranslatorCanvas(sizeOptions, rangeContainerCanvas, scaleLabelsAreaHeight));
that._scaleOptions.ticksInfo = getTicksInfo(that, that._scaleOptions, that.translators, rangeContainerCanvas.width);
that._testTicksInfo = that._scaleOptions.ticksInfo;
that._selectedRange = selectedRange;
if (seriesDataSource)
seriesDataSource.adjustSeriesDimensions(that.translators);
that.rangeContainer.applyOptions({
canvas: rangeContainerCanvas,
scaleLabelsAreaHeight: scaleLabelsAreaHeight,
sliderMarkerSpacing: sliderMarkerSpacing,
translators: that.translators,
selectedRange: selectedRange,
scale: that._scaleOptions,
behavior: that.option('behavior'),
background: that.option('background'),
chart: that.option('chart'),
seriesDataSource: seriesDataSource,
sliderMarker: sliderMarkerOptions,
sliderHandle: that.option('sliderHandle'),
shutter: that.option('shutter'),
selectedRangeChanged: createSelectedRangeChangedFunction(that),
setSelectedRange: function(selectedRange) {
that.setSelectedRange(selectedRange)
}
});
that._isUpdating = false
};
var createSelectedRangeChangedFunction = function(that) {
return function(selectedRange, blockSelectedRangeChanged) {
var selectedRangeChanged = that.option('selectedRangeChanged');
that.option('selectedRange', selectedRange);
if (selectedRangeChanged && !blockSelectedRangeChanged)
setTimeout(function() {
selectedRangeChanged.call(null, selectedRange)
})
}
};
var calculateSize = function(that) {
var $container = that.container,
size = that.option('size') || {},
result = {
width: size.width,
height: size.height
};
if ($container) {
if (!result.width)
result.width = $container.width();
if (!result.height)
result.height = $container.height()
}
that.canvas = result;
return result
};
var updateRendererSize = function(that, size) {
var renderer = that.renderer;
if (renderer.isInitialized())
renderer.getRoot().applySettings({
width: size.width,
height: size.height
});
else {
renderer.recreateCanvas(size.width, size.height);
renderer.draw(that.container[0])
}
};
var prepareChartThemeOptions = function(that, options) {
var chartTheme,
chartOption = that.option('chart') || {};
if (!chartOption.theme && options && options.theme) {
chartTheme = options.theme;
if (chartTheme) {
if (typeof chartTheme === 'object') {
chartTheme = chartTheme.chart || {};
chartTheme.name = options.theme.name
}
chartOption.theme = chartTheme
}
}
};
var initSelection = function(that, scaleOptions) {
var selectedRangeOptions = that.option('selectedRange'),
startValue,
endValue,
parser = scaleOptions.parser || function() {
return null
},
parseValue = function(value, entity) {
var parsedValue,
result = scaleOptions[entity];
if (_isDefined(value))
parsedValue = parser(value);
if (!_isDefined(parsedValue))
that._incidentOccured("E2203", [entity]);
else
result = parsedValue;
return result
};
if (!selectedRangeOptions)
return {
startValue: scaleOptions.startValue,
endValue: scaleOptions.endValue
};
else {
startValue = parseValue(selectedRangeOptions.startValue, 'startValue');
startValue = that.rangeContainer.slidersContainer.truncateSelectedRange(startValue, scaleOptions);
endValue = parseValue(selectedRangeOptions.endValue, 'endValue');
endValue = that.rangeContainer.slidersContainer.truncateSelectedRange(endValue, scaleOptions);
return {
startValue: startValue,
endValue: endValue
}
}
};
var _isSizeChanged = function(that) {
var actualSize = that._actualSize,
newSize = calculateSize(that);
return actualSize && (actualSize.width !== newSize.width || actualSize.height !== newSize.height)
};
return {
isSizeChanged: function() {
return _isSizeChanged(this)
},
_setDefaultOptions: function() {
this.callBase();
this.option(defaultRangeSelectorOptions)
},
_dataSourceOptions: function() {
return {
paginate: false,
_preferSync: true
}
},
_init: function() {
var that = this;
that.container = getContainer(that);
clearContainer(that.container);
that.renderer = createRenderer(that);
that.rangeContainer = createRangeContainer(that.renderer);
that.callBase();
that._reinitDataSource()
},
_reinitDataSource: function() {
this._refreshDataSource()
},
_dispose: function() {
var that = this,
disposeObject = function(propName) {
that[propName] && that[propName].dispose(),
that[propName] = null
};
that.callBase();
disposeObject("renderer");
that.translators = null;
disposeObject("rangeContainer")
},
_initOptions: function(options) {
var that = this,
themeManager;
that._optionsInitializing = true;
options = options || {};
that._userOptions = $.extend(true, {}, options);
themeManager = createThemeManager(options.theme);
themeManager.setBackgroundColor(options.containerBackgroundColor);
that.option(themeManager.applyRangeSelectorTheme(options));
prepareChartThemeOptions(that, options);
if (options.background)
that._userBackgroundColor = options.background.color
},
_refresh: function() {
var that = this,
callBase = that.callBase;
that._endLoading(function() {
callBase.call(that)
})
},
_render: function(isResizing) {
var that = this,
currentAnimationEnabled,
behaviorOptions;
that._optionsInitializing = false;
applyOptions(that);
if (!that.stopRedraw) {
if (isResizing) {
behaviorOptions = that.option('behavior');
currentAnimationEnabled = behaviorOptions.animationEnabled;
behaviorOptions.animationEnabled = false;
that.rangeContainer.redraw();
behaviorOptions.animationEnabled = currentAnimationEnabled
}
else
that.rangeContainer.redraw();
!isResizing && (!that._dataSource || that._dataSource && that._dataSource.isLoaded()) && that.hideLoadingIndicator()
}
that._drawn();
that.__rendered && that.__rendered()
},
_optionChanged: function(name, value, prevValue) {
var that = this;
if (!that._optionsInitializing)
dataUtils.compileSetter(name)(that._userOptions, value, {
functionsAsIs: true,
merge: true
});
if (name === "dataSource") {
that._reinitDataSource();
that._invalidate()
}
else if (name === "selectedRange")
that.setSelectedRange(that.option('selectedRange'));
else if (name === "selectedRangeChanged")
that.rangeContainer.slidersContainer.selectedRangeChanged = createSelectedRangeChangedFunction(that);
else if (name === 'containerBackgroundColor' || name === 'theme') {
that._initOptions(that._userOptions);
that._invalidate()
}
else
that.callBase(name, value, prevValue)
},
_resize: function() {
if (_isSizeChanged(this))
this._render(true)
},
_handleDataSourceChanged: function() {
var that = this;
that._endLoading(function() {
if (that.renderer.isInitialized())
that._render()
})
},
getSelectedRange: function() {
var that = this;
var selectedRange = that.rangeContainer.slidersContainer.getSelectedRange();
return {
startValue: selectedRange.startValue,
endValue: selectedRange.endValue
}
},
setSelectedRange: function(selectedRange) {
var that = this;
if (that._isUpdating || !selectedRange)
return;
var oldSelectedRange = that.rangeContainer.slidersContainer.getSelectedRange();
if (oldSelectedRange && oldSelectedRange.startValue === selectedRange.startValue && oldSelectedRange.endValue === selectedRange.endValue)
return;
that.rangeContainer.slidersContainer.setSelectedRange(selectedRange)
},
resetSelectedRange: function(blockSelectedRangeChanged) {
var that = this;
that.setSelectedRange({
startValue: that._scaleOptions.startValue,
endValue: that._scaleOptions.endValue,
blockSelectedRangeChanged: blockSelectedRangeChanged
})
},
render: function(isResizing) {
this._render(isResizing);
return this
}
}
}()).include(DX.ui.DataHelperMixin)
})(jQuery, DevExpress);
/*! Module viz-rangeselector, file rangeContainer.js */
(function($, DX, undefined) {
var rangeSelector = DX.viz.rangeSelector;
rangeSelector.RangeContainer = rangeSelector.BaseVisualElement.inherit(function() {
var ctor = function(renderer) {
this.callBase(renderer);
this.slidersContainer = createSlidersContainer(renderer);
this.rangeView = createRangeView(renderer);
this.scale = createScale(renderer)
};
var _applyOptions = function(options) {
var that = this,
isEmpty = options.scale.isEmpty,
viewCanvas = {
left: options.canvas.left,
top: options.canvas.top,
width: options.canvas.width,
height: options.canvas.height >= options.scaleLabelsAreaHeight ? options.canvas.height - options.scaleLabelsAreaHeight : 0
};
that._viewCanvas = viewCanvas;
that.slidersContainer.applyOptions({
canvas: viewCanvas,
translator: options.translators.x,
scale: options.scale,
selectedRange: options.selectedRange,
sliderMarker: options.sliderMarker,
sliderHandle: options.sliderHandle,
shutter: options.shutter,
behavior: options.behavior,
selectedRangeChanged: options.selectedRangeChanged,
isEmpty: isEmpty
});
that.rangeView.applyOptions({
canvas: viewCanvas,
translators: options.translators,
background: options.background,
chart: options.chart,
seriesDataSource: options.seriesDataSource,
behavior: options.behavior,
isEmpty: isEmpty
});
that.scale.applyOptions({
canvas: options.canvas,
translator: options.translators.x,
scale: options.scale,
hideLabels: isEmpty,
scaleLabelsAreaHeight: options.scaleLabelsAreaHeight,
setSelectedRange: options.setSelectedRange
})
};
var createSlidersContainer = function(options) {
return rangeSelector.rangeSelectorFactory.createSlidersContainer(options)
};
var createScale = function(options) {
return rangeSelector.rangeSelectorFactory.createScale(options)
};
var createRangeView = function(options) {
return rangeSelector.rangeSelectorFactory.createRangeView(options)
};
var _createClipRectCanvas = function(canvas, sliderMarkerSpacing) {
return {
left: canvas.left - sliderMarkerSpacing.left,
top: canvas.top - sliderMarkerSpacing.top,
width: canvas.width + sliderMarkerSpacing.right + sliderMarkerSpacing.left,
height: canvas.height + sliderMarkerSpacing.bottom + sliderMarkerSpacing.top
}
};
var _draw = function() {
var that = this,
containerGroup,
rangeViewGroup,
slidersContainerGroup,
scaleGroup,
trackersGroup,
clipRectCanvas = _createClipRectCanvas(that._options.canvas, that._options.sliderMarkerSpacing),
viewCanvas = that._viewCanvas;
that._clipRect = that._renderer.createClipRect(clipRectCanvas.left, clipRectCanvas.top, clipRectCanvas.width, clipRectCanvas.height).append();
containerGroup = that._renderer.createGroup({
'class': 'rangeContainer',
clipId: that._clipRect.id
}).append();
that._viewClipRect = that._renderer.createClipRect(viewCanvas.left, viewCanvas.top, viewCanvas.width, viewCanvas.height).append();
rangeViewGroup = that._renderer.createGroup({
'class': 'view',
clipId: that._viewClipRect.id
});
rangeViewGroup.append(containerGroup);
that.rangeView.redraw(rangeViewGroup);
slidersContainerGroup = that._renderer.createGroup({'class': 'slidersContainer'});
slidersContainerGroup.append(containerGroup);
that.slidersContainer.redraw(slidersContainerGroup);
scaleGroup = that._renderer.createGroup({'class': 'scale'});
scaleGroup.append(containerGroup);
that.scale.redraw(scaleGroup);
trackersGroup = that._renderer.createGroup({'class': 'trackers'});
trackersGroup.append(containerGroup);
that._trackersGroup = trackersGroup;
that.slidersContainer.appendTrackers(trackersGroup)
};
var _update = function() {
var that = this,
clipRectCanvas = _createClipRectCanvas(that._options.canvas, that._options.sliderMarkerSpacing),
viewCanvas = that._viewCanvas;
that._clipRect.updateRectangle({
x: clipRectCanvas.left,
y: clipRectCanvas.top,
width: clipRectCanvas.width,
height: clipRectCanvas.height
});
that._viewClipRect.updateRectangle({
x: viewCanvas.left,
y: viewCanvas.top,
width: viewCanvas.width,
height: viewCanvas.height
});
that.rangeView.redraw();
that.slidersContainer.redraw();
that.slidersContainer.appendTrackers(that._trackersGroup);
that.scale.redraw()
};
var dispose = function() {
this.slidersContainer.dispose();
this.slidersContainer = null
};
var prototypeObject = {
createSlidersContainer: createSlidersContainer,
createScale: createScale,
ctor: ctor,
dispose: dispose,
_applyOptions: _applyOptions,
_draw: _draw,
_update: _update
};
return prototypeObject
}())
})(jQuery, DevExpress);
/*! Module viz-rangeselector, file scale.js */
(function($, DX, undefined) {
var rangeSelector = DX.viz.rangeSelector,
formatHelper = DX.formatHelper,
utils = DX.utils;
var SCALE_TEXT_SPACING = 5;
rangeSelector.Scale = rangeSelector.BaseVisualElement.inherit({
_setupDateUnitInterval: function(scaleOptions) {
var key,
hasObjectSingleField = function(object) {
var fieldsCounter = 0;
$.each(object, function() {
return ++fieldsCounter < 2
});
return fieldsCounter === 1
},
millisecTickInterval,
majorTickInterval = scaleOptions.ticksInfo.majorTickInterval,
majorTicks = scaleOptions.ticksInfo.majorTicks;
if (scaleOptions.valueType === 'datetime') {
if (utils.isObject(majorTickInterval) && !hasObjectSingleField(majorTickInterval))
utils.logger.warn('More than one field is specified within the object assigned to the "tickInterval" option. Assign an object with a single field specified (days, hours or a similar one).');
if (majorTicks && majorTicks.autoArrangementStep > 1) {
if (utils.isString(majorTickInterval))
majorTickInterval = utils.getDateIntervalByString(majorTickInterval);
for (key in majorTickInterval)
if (majorTickInterval.hasOwnProperty(key)) {
majorTickInterval[key] *= majorTicks.autoArrangementStep;
millisecTickInterval = utils.convertDateTickIntervalToMilliseconds(majorTickInterval)
}
majorTickInterval = utils.convertMillisecondsToDateUnits(millisecTickInterval)
}
this.dateUnitInterval = utils.getDateUnitInterval(majorTickInterval)
}
},
_prepareDatesDifferences: function(datesDifferences, tickInterval) {
var deleteDifferent = tickInterval,
dateUnitInterval,
i;
if (deleteDifferent === 'week')
deleteDifferent = 'day';
if (deleteDifferent === 'quarter')
deleteDifferent = 'month';
if (datesDifferences[deleteDifferent])
for (i = 0; i < utils.dateUnitIntervals.length; i++) {
dateUnitInterval = utils.dateUnitIntervals[i];
if (datesDifferences[dateUnitInterval]) {
datesDifferences[dateUnitInterval] = false;
datesDifferences.count--
}
if (dateUnitInterval === deleteDifferent)
break
}
},
_getMarkerDate: function(date, tickInterval) {
var markerDate = new Date(date.getTime()),
month = 0;
switch (tickInterval) {
case'quarter':
month = formatHelper.getFirstQuarterMonth(date.getMonth());
case'month':
markerDate.setMonth(month);
case'week':
case'day':
markerDate.setDate(1);
case'hour':
markerDate.setHours(0, 0, 0, 0);
break;
case'millisecond':
markerDate.setMilliseconds(0);
break;
case'second':
markerDate.setSeconds(0, 0);
break;
case'minute':
markerDate.setMinutes(0, 0, 0);
break
}
return markerDate
},
_drawDateMarker: function(date, options) {
var labelPosX,
labelPosY,
dateFormated,
scaleOptions,
textElement;
if (options.x === null)
return;
scaleOptions = this._options.scale;
this.lineOptions['class'] = 'dx-range-selector-date-marker';
this._renderer.createLine(options.x, options.y, options.x, options.y + scaleOptions.marker.separatorHeight, this.lineOptions).append(options.group);
dateFormated = this._getLabel(date, options.label);
labelPosX = options.x + scaleOptions.tick.width + scaleOptions.marker.textLeftIndent;
labelPosY = options.y + scaleOptions.marker.textTopIndent + scaleOptions.label.font.size;
this.textOptions.align = 'left';
textElement = this._renderer.createText(dateFormated, labelPosX, labelPosY, this.textOptions).append(options.group);
return labelPosX + textElement.getBBox().width
},
_drawDateMarkers: function(dates, group) {
var dateMarker,
i,
datesDifferences,
markerDate,
posX,
prevMarkerRightX = -1;
if (this._options.scale.valueType !== 'datetime' || !this.visibleMarkers)
return;
var markerDatePositions = [];
if (dates.length > 1) {
for (i = 1; i < dates.length; i++) {
datesDifferences = utils.getDatesDifferences(dates[i - 1], dates[i]);
this._prepareDatesDifferences(datesDifferences, this.dateUnitInterval);
if (datesDifferences.count > 0) {
markerDate = this._getMarkerDate(dates[i], this.dateUnitInterval);
this.markerDates = this.markerDates || [];
this.markerDates.push(markerDate);
posX = this.translator.translate(markerDate);
if (posX > prevMarkerRightX) {
posX !== null && markerDatePositions.push({
date: markerDate,
posX: posX
});
prevMarkerRightX = this._drawDateMarker(markerDate, {
group: group,
y: this._options.canvas.top + this._options.canvas.height - this.markersAreaHeight + this._options.scale.marker.topIndent,
x: posX,
label: this._getLabelFormatOptions(formatHelper.getDateFormatByDifferences(datesDifferences))
})
}
}
}
this._initializeMarkersEvents(markerDatePositions, group)
}
},
_getLabelFormatOptions: function(formatString) {
if (!utils.isDefined(this._options.scale.marker.label.format))
return $.extend({}, this._options.scale.marker.label, {format: formatString});
return this._options.scale.marker.label
},
_calculateRangeByMarkerPosition: function(posX, markerDatePositions, scaleOptions) {
var selectedRange = {},
i,
position;
for (i = 0; i < markerDatePositions.length; i++) {
position = markerDatePositions[i];
if (!scaleOptions.inverted) {
if (posX >= position.posX)
selectedRange.startValue = position.date;
else if (!selectedRange.endValue)
selectedRange.endValue = position.date
}
else if (posX < position.posX)
selectedRange.endValue = position.date;
else if (!selectedRange.startValue)
selectedRange.startValue = position.date
}
selectedRange.startValue = selectedRange.startValue || scaleOptions.startValue;
selectedRange.endValue = selectedRange.endValue || scaleOptions.endValue;
return selectedRange
},
_initializeMarkersEvents: function(markerDatePositions, group) {
var that = this,
markersAreaTop = this._options.canvas.top + this._options.canvas.height - this.markersAreaHeight + this._options.scale.marker.topIndent,
markersTracker,
svgOffsetLeft,
index,
posX,
selectedRange;
if (markerDatePositions.length > 0) {
markersTracker = that._renderer.createRect(that._options.canvas.left, markersAreaTop, that._options.canvas.width, that._options.scale.marker.separatorHeight, 0, {
fill: 'grey',
stroke: 'grey',
opacity: 0.0001
});
markersTracker.append(group);
markersTracker.on(rangeSelector.events.start, function(e) {
svgOffsetLeft = rangeSelector.utils.getRootOffsetLeft(that._renderer);
posX = rangeSelector.utils.getEventPageX(e) - svgOffsetLeft;
selectedRange = that._calculateRangeByMarkerPosition(posX, markerDatePositions, that._options.scale);
that._options.setSelectedRange(selectedRange)
});
that._markersTracker = markersTracker
}
},
_getLabel: function(value, options) {
var formatObject = {
value: value,
valueText: formatHelper.format(value, options.format, options.precision)
};
return String(utils.isFunction(options.customizeText) ? options.customizeText.call(formatObject, formatObject) : formatObject.valueText)
},
_drawLabel: function(value, group) {
var textY = this._options.canvas.top + this._options.canvas.height - this.markersAreaHeight,
textElement = this._renderer.createText(this._getLabel(value, this._options.scale.label), this.translator.translate(value), textY, this.textOptions);
textElement.append(group);
this.textElements = this.textElements || [];
this.textElements.push(textElement)
},
_drawTick: function(value, group) {
this.lineOptions['class'] = 'dx-range-selector-tick';
var secondY = this._options.canvas.top + this._options.canvas.height - this.scaleLabelsAreaHeight,
posX = this.translator.translate(value),
tickElement = this._renderer.createLine(posX, this._options.canvas.top, posX, secondY, this.lineOptions).append(group);
this.tickElements = this.tickElements || [];
this.tickElements.push(tickElement)
},
_redraw: function(group, isOptimize) {
var that = this,
scaleOptions = that._options.scale,
ticksGroup = that._renderer.createGroup(),
labelsGroup = that._renderer.createGroup().append(group),
majorTicks = scaleOptions.ticksInfo.majorTicks,
minorTicks = scaleOptions.ticksInfo.minorTicks,
customBoundaryTicks = scaleOptions.ticksInfo.customBoundaryTicks,
hideLabels = that._options.hideLabels || majorTicks.hideLabels || !scaleOptions.label.visible,
i;
for (i = 0; i < majorTicks.length; i++) {
if (!hideLabels)
that._drawLabel(majorTicks[i], labelsGroup);
that._drawTick(majorTicks[i], ticksGroup)
}
if (scaleOptions.showMinorTicks)
for (i = 0; i < minorTicks.length; i++)
that._drawTick(minorTicks[i], ticksGroup);
for (i = 0; i < customBoundaryTicks.length; i++)
that._drawTick(customBoundaryTicks[i], ticksGroup);
ticksGroup.append(group);
that._drawDateMarkers(majorTicks, labelsGroup)
},
_applyOptions: function(options) {
var scaleOptions = options.scale,
labelsAreaHeight;
this.textOptions = {
align: 'center',
'class': 'dx-range-selector-scale',
font: scaleOptions.label.font,
style: {'-webkit-user-select': 'none'}
};
this.lineOptions = {
strokeWidth: scaleOptions.tick.width,
stroke: scaleOptions.tick.color,
strokeOpacity: scaleOptions.tick.opacity
};
this._setupDateUnitInterval(scaleOptions);
this.visibleMarkers = scaleOptions.marker.visible === undefined ? true : scaleOptions.marker.visible;
labelsAreaHeight = scaleOptions.label.visible ? scaleOptions.label.topIndent + scaleOptions.label.font.size : 0;
this.scaleLabelsAreaHeight = options.scaleLabelsAreaHeight;
this.markersAreaHeight = this.scaleLabelsAreaHeight - labelsAreaHeight;
this.translator = options.translator
},
_draw: function(group) {
this._redraw(group, false)
},
_update: function(group) {
var callBase = this.callBase;
if (this._markersTracker)
this._markersTracker.off(rangeSelector.events.start, '**');
this.callBase = callBase;
this.callBase(group)
}
})
})(jQuery, DevExpress);
/*! Module viz-rangeselector, file rangeFactory.js */
(function($, DX, undefined) {
var rangeSelector = DX.viz.rangeSelector,
renderers = DX.viz.renderers;
rangeSelector.rangeSelectorFactory = function() {
return {
createRangeContainer: function(rangeContainerOptions) {
return new rangeSelector.RangeContainer(rangeContainerOptions)
},
createSlidersContainer: function(options) {
return new rangeSelector.SlidersContainer(options)
},
createScale: function(options) {
return new rangeSelector.Scale(options)
},
createSliderMarker: function(options) {
return new rangeSelector.SliderMarker(options)
},
createRangeView: function(options) {
return new rangeSelector.RangeView(options)
},
createThemeManager: function(options) {
return new rangeSelector.ThemeManager(options)
},
createSlider: function(renderer, sliderIndex) {
return new rangeSelector.Slider(renderer, sliderIndex)
},
createSlidersEventsManager: function(renderer, slidersController, processSelectionChanged) {
return new rangeSelector.SlidersEventsManager(renderer, slidersController, processSelectionChanged)
},
createSlidersController: function(sliders) {
return new rangeSelector.SlidersController(sliders)
}
}
}()
})(jQuery, DevExpress);
/*! Module viz-rangeselector, file slidersContainer.js */
(function($, DX, undefined) {
var rangeSelector = DX.viz.rangeSelector,
utils = DX.utils;
var msPointerEnabled = window.navigator.msPointerEnabled || window.navigator.pointerEnabled;
var isNumber = DX.utils.isNumber;
var isDate = DX.utils.isDate;
var START_VALUE_INDEX = 0,
END_VALUE_INDEX = 1;
rangeSelector.SlidersContainer = rangeSelector.BaseVisualElement.inherit(function() {
var prototypeObject = {
getController: function() {
return this._controller
},
_drawAreaTracker: function(group) {
var that = this,
areaTracker,
selectedAreaTracker;
areaTracker = that._renderer.createRect(that._options.canvas.left, that._options.canvas.top, that._options.canvas.width, that._options.canvas.height, 0, {
fill: 'grey',
stroke: 'grey',
opacity: 0.0001
});
areaTracker.append(group);
selectedAreaTracker = that._renderer.createRect(that._options.canvas.left, that._options.canvas.top, that._options.canvas.width, that._options.canvas.height, 0, {
fill: 'grey',
stroke: 'grey',
opacity: 0.0001,
style: {cursor: 'pointer'}
});
selectedAreaTracker.append(group);
that._controller.setAreaTrackers(areaTracker, selectedAreaTracker)
},
dispose: function() {
this._eventsManager.dispose();
this._eventManager = null
},
_processSelectionChanged: function(moving, blockSelectedRangeChanged) {
var that = this,
equalLastSelectedRange = function(selectedRange) {
return selectedRange && that._lastSelectedRange.startValue === selectedRange.startValue && that._lastSelectedRange.endValue === selectedRange.endValue
},
selectedRange = that.getSelectedRange();
if ((!moving || (that._options.behavior.callSelectedRangeChanged || '').toLowerCase() === "onmoving") && that._options.selectedRangeChanged && !equalLastSelectedRange(selectedRange)) {
that._updateLastSelectedRange(selectedRange);
if (typeof that._options.selectedRangeChanged === 'function')
that._options.selectedRangeChanged.call(null, selectedRange, blockSelectedRangeChanged);
if (!moving && !equalLastSelectedRange(selectedRange))
that.setSelectedRange(selectedRange)
}
},
_updateLastSelectedRange: function(selectedRange) {
selectedRange = selectedRange || this._options.selectedRange;
this._lastSelectedRange = {
startValue: selectedRange.startValue,
endValue: selectedRange.endValue
}
},
_createSlider: function(sliderIndex) {
return rangeSelector.rangeSelectorFactory.createSlider(this._renderer, sliderIndex)
},
_createSlidersController: function(sliders) {
return rangeSelector.rangeSelectorFactory.createSlidersController(sliders)
},
_createSlidersEventsManager: function(controller) {
var that = this;
return rangeSelector.rangeSelectorFactory.createSlidersEventsManager(that._renderer, controller, function(moving) {
that._processSelectionChanged(moving)
})
},
ctor: function(renderer) {
var that = this,
sliders;
that.callBase(renderer);
sliders = [that._createSlider(START_VALUE_INDEX), that._createSlider(END_VALUE_INDEX)];
that._controller = that._createSlidersController(sliders);
that._eventsManager = that._createSlidersEventsManager(that._controller);
that._lastSelectedRange = {}
},
getSelectedRange: function() {
return this._controller.getSelectedRange()
},
truncateSelectedRange: function(value, scaleOptions) {
var min = scaleOptions.startValue > scaleOptions.endValue ? scaleOptions.endValue : scaleOptions.startValue,
max = scaleOptions.startValue > scaleOptions.endValue ? scaleOptions.startValue : scaleOptions.endValue;
if (value < min)
value = min;
if (value > max)
value = max;
return value
},
setSelectedRange: function(selectedRange) {
var that = this,
scale = that._options.scale,
startValue,
endValue,
currentSelectedRange = that._options.selectedRange;
if (selectedRange) {
startValue = selectedRange.startValue;
endValue = selectedRange.endValue
}
if (isNumber(scale.startValue) && isNumber(startValue) || isDate(scale.startValue) && isDate(startValue))
currentSelectedRange.startValue = startValue;
if (isNumber(scale.endValue) && isNumber(endValue) || isDate(scale.endValue) && isDate(endValue))
currentSelectedRange.endValue = endValue;
currentSelectedRange.startValue = that.truncateSelectedRange(currentSelectedRange.startValue, scale);
currentSelectedRange.endValue = that.truncateSelectedRange(currentSelectedRange.endValue, scale);
that._controller.applySelectedRange(currentSelectedRange);
that._controller.applyPosition();
that._processSelectionChanged(false, selectedRange && selectedRange.blockSelectedRangeChanged)
},
appendTrackers: function(group) {
this._controller.appendTrackers(group)
},
_applyOptions: function(options) {
var that = this;
that._controller.applyOptions({
translator: options.translator,
canvas: options.canvas,
sliderMarker: options.sliderMarker,
sliderHandle: options.sliderHandle,
shutter: options.shutter,
scale: options.scale,
behavior: options.behavior
});
that._eventsManager.applyOptions({behavior: options.behavior})
},
_draw: function(group) {
var that = this,
rootElement;
if (msPointerEnabled) {
rootElement = that._renderer.getRoot();
rootElement && (rootElement.element.style.msTouchAction = "pinch-zoom")
}
that._controller.redraw(group);
that._drawAreaTracker(group);
that._eventsManager.initialize();
that._update()
},
_update: function() {
var that = this,
isEmpty = that._options.isEmpty;
that._eventsManager.setEnabled(!isEmpty);
that._controller.applySelectedRange(isEmpty ? {} : that._options.selectedRange);
that._controller.applyPosition(that.isDrawn());
that._updateLastSelectedRange();
that._controller.redraw()
}
};
return prototypeObject
}())
})(jQuery, DevExpress);
/*! Module viz-rangeselector, file slidersController.js */
(function($, DX, undefined) {
var rangeSelector = DX.viz.rangeSelector,
utils = DX.utils;
var START_VALUE_INDEX = 0,
END_VALUE_INDEX = 1;
rangeSelector.SlidersController = DX.Class.inherit(function() {
return {
ctor: function(sliders) {
this._sliders = sliders;
sliders[START_VALUE_INDEX].setAnotherSlider(sliders[END_VALUE_INDEX]);
sliders[END_VALUE_INDEX].setAnotherSlider(sliders[START_VALUE_INDEX])
},
setAreaTrackers: function(areaTracker, selectedAreaTracker) {
this._areaTracker = areaTracker;
this._selectedAreaTracker = selectedAreaTracker
},
applyOptions: function(options) {
var that = this,
values = null;
that._options = options;
that.getSlider(START_VALUE_INDEX).applyOptions(options);
that.getSlider(END_VALUE_INDEX).applyOptions(options);
if (options.behavior.snapToTicks) {
values = options.scale.ticksInfo.fullTicks;
if (values.length > 1 && values[0] > values[values.length - 1])
values = values.reverse()
}
that.getSlider(START_VALUE_INDEX).setAvailableValues(values);
that.getSlider(END_VALUE_INDEX).setAvailableValues(values)
},
processDocking: function(sliderIndex) {
var that = this;
if (sliderIndex !== undefined)
that.getSlider(sliderIndex).processDocking();
else {
that.getSlider(START_VALUE_INDEX).processDocking();
that.getSlider(END_VALUE_INDEX).processDocking()
}
that.setTrackersCursorStyle('default');
that.applyAreaTrackersPosition()
},
getSelectedRangeInterval: function() {
var that = this,
type = that._options.scale.type,
base = that._options.scale.logarithmBase,
startValue = that.getSlider(START_VALUE_INDEX).getValue(),
endValue = that.getSlider(END_VALUE_INDEX).getValue();
if (type === 'logarithmic')
return rangeSelector.utils.getInterval(utils.getLog(startValue, base), utils.getLog(endValue, base));
else
return rangeSelector.utils.getInterval(startValue, endValue)
},
moveSliders: function(postitionDelta, selectedRangeInterval) {
var that = this;
that.getSlider(START_VALUE_INDEX).setPosition(that.getSlider(START_VALUE_INDEX).getPosition() + postitionDelta, false, selectedRangeInterval);
that.applyPosition(true)
},
moveSlider: function(sliderIndex, fastSwap, position, offsetPosition, startOffsetPosition, startOffsetPositionChangedCallback) {
var that = this,
slider = that.getSlider(sliderIndex),
anotherSlider = slider.getAnotherSlider(),
anotherSliderIndex = anotherSlider.getIndex(),
doSwap;
if (slider.canSwap())
if (sliderIndex === START_VALUE_INDEX ? position > anotherSlider.getPosition() : position < anotherSlider.getPosition()) {
doSwap = fastSwap;
if (!fastSwap)
if (Math.abs(offsetPosition) >= Math.abs(startOffsetPosition) && offsetPosition * startOffsetPosition < 0) {
doSwap = true;
position += 2 * startOffsetPosition;
startOffsetPositionChangedCallback(-startOffsetPosition)
}
if (doSwap) {
that.swapSliders();
anotherSlider.applyPosition(true)
}
}
slider.setPosition(position, true);
slider.applyPosition(true);
that.applyAreaTrackersPosition();
that.setTrackersCursorStyle('w-resize')
},
applySelectedAreaCenterPosition: function(pos) {
var that = this,
slidersContainerHalfWidth = (that.getSlider(END_VALUE_INDEX).getPosition() - that.getSlider(START_VALUE_INDEX).getPosition()) / 2,
selectedRangeInterval = that.getSelectedRangeInterval();
that.getSlider(START_VALUE_INDEX).setPosition(pos - slidersContainerHalfWidth, false, selectedRangeInterval);
that.applyPosition();
that.processDocking()
},
processManualSelection: function(startPosition, endPosition, eventArgs) {
var that = this,
animateSliderIndex,
movingSliderIndex,
positionRange = [Math.min(startPosition, endPosition), Math.max(startPosition, endPosition)];
animateSliderIndex = startPosition < endPosition ? START_VALUE_INDEX : END_VALUE_INDEX;
movingSliderIndex = startPosition < endPosition ? END_VALUE_INDEX : START_VALUE_INDEX;
that.getSlider(movingSliderIndex).setPosition(positionRange[movingSliderIndex]);
that.getSlider(animateSliderIndex).setPosition(positionRange[animateSliderIndex]);
that.getSlider(movingSliderIndex).setPosition(positionRange[movingSliderIndex], true);
that.getSlider(movingSliderIndex).startEventHandler(eventArgs);
that.getSlider(animateSliderIndex).processDocking();
that.getSlider(movingSliderIndex).applyPosition(true)
},
applySelectedRange: function(selectedRange) {
var that = this,
inverted = that._options.scale.inverted;
utils.debug.assertParam(selectedRange, 'selectedRange not passed');
if (!inverted && selectedRange.startValue > selectedRange.endValue || inverted && selectedRange.startValue < selectedRange.endValue) {
that.getSlider(START_VALUE_INDEX).setValue(selectedRange.endValue);
that.getSlider(END_VALUE_INDEX).setValue(selectedRange.startValue)
}
else {
that.getSlider(START_VALUE_INDEX).setValue(selectedRange.startValue);
that.getSlider(END_VALUE_INDEX).setValue(selectedRange.endValue)
}
},
getSelectedRange: function() {
var that = this;
return {
startValue: that.getSlider(START_VALUE_INDEX).getValue(),
endValue: that.getSlider(END_VALUE_INDEX).getValue()
}
},
swapSliders: function() {
var that = this;
that._sliders.reverse();
that.getSlider(START_VALUE_INDEX).changeLocation();
that.getSlider(END_VALUE_INDEX).changeLocation()
},
applyAreaTrackersPosition: function() {
var that = this,
selectedRange = that.getSelectedRange(),
scaleOptions = that._options.scale,
width = that.getSlider(END_VALUE_INDEX).getPosition() - that.getSlider(START_VALUE_INDEX).getPosition(),
options = {
x: that.getSlider(START_VALUE_INDEX).getPosition(),
width: width < 0 ? 0 : width,
y: that._options.canvas.top,
height: that._options.canvas.height,
style: {cursor: scaleOptions.endValue - scaleOptions.startValue === selectedRange.endValue - selectedRange.startValue ? 'default' : 'pointer'}
};
that._selectedAreaTracker.applySettings(options);
that._areaTracker.applySettings({
x: that._options.canvas.left,
width: that._options.canvas.width,
y: that._options.canvas.top,
height: that._options.canvas.height
})
},
applyPosition: function(disableAnimation) {
var that = this;
that.getSlider(START_VALUE_INDEX).applyPosition(disableAnimation);
that.getSlider(END_VALUE_INDEX).applyPosition(disableAnimation);
that.applyAreaTrackersPosition()
},
redraw: function(group) {
var that = this;
that.getSlider(START_VALUE_INDEX).redraw(group);
that.getSlider(END_VALUE_INDEX).redraw(group)
},
appendTrackers: function(group) {
var that = this;
if (that._areaTracker && that._selectedAreaTracker) {
that._areaTracker.append(group);
that._selectedAreaTracker.append(group)
}
that.getSlider(START_VALUE_INDEX).appendTrackers(group);
that.getSlider(END_VALUE_INDEX).appendTrackers(group)
},
getSlider: function(sliderIndex) {
return this._sliders[sliderIndex]
},
getAreaTracker: function() {
return this._areaTracker
},
getSelectedAreaTracker: function() {
return this._selectedAreaTracker
},
setTrackersCursorStyle: function(style) {
var that = this;
that._selectedAreaTracker.applySettings({style: {cursor: style}});
that._areaTracker.applySettings({style: {cursor: style}})
}
}
}())
})(jQuery, DevExpress);
/*! Module viz-rangeselector, file slidersEventsManager.js */
(function($, DX, undefined) {
var rangeSelector = DX.viz.rangeSelector,
utils = DX.utils,
MIN_MANUAL_SELECTING_WIDTH = 10,
START_VALUE_INDEX = 0,
END_VALUE_INDEX = 1,
addNamespace = DX.ui.events.addNamespace,
setEvents = function() {
var win = window;
win = DX.viz.rangeSelector.mockWindow || window;
var touchSupport = "ontouchstart" in win,
msPointerEnabled = win.navigator.msPointerEnabled,
pointerEnabled = win.navigator.pointerEnabled;
rangeSelector.events = {
start: pointerEnabled ? "pointerdown" : msPointerEnabled ? "MSPointerDown" : touchSupport ? "touchstart mousedown" : "mousedown",
move: pointerEnabled ? "pointermove" : msPointerEnabled ? "MSPointerMove" : touchSupport ? "touchmove mousemove" : "mousemove",
end: pointerEnabled ? "pointerup pointercancel" : msPointerEnabled ? "MSPointerUp MSPointerCancel" : touchSupport ? "touchend mouseup" : "mouseup"
}
},
_SlidersEventManager,
getEventPageX = rangeSelector.utils.getEventPageX,
rangeSelectorCount = 0;
setEvents();
var isLeftButtonPressed = function(event) {
var e = event || window.event,
originalEvent = e.originalEvent,
touches = e.touches,
pointerType = originalEvent ? originalEvent.pointerType : false,
eventTouches = originalEvent ? originalEvent.touches : false,
isIE8LeftClick = e.which === undefined && e.button === 1,
isMSPointerLeftClick = originalEvent && pointerType !== undefined && (pointerType === (originalEvent.MSPOINTER_TYPE_TOUCH || 'touch') || pointerType === (originalEvent.MSPOINTER_TYPE_MOUSE || 'mouse') && originalEvent.buttons === 1),
isLeftClick = isIE8LeftClick || e.which === 1,
isTouches = touches && touches.length > 0 || eventTouches && eventTouches.length > 0;
return isLeftClick || isMSPointerLeftClick || isTouches
};
var isMultiTouches = function(event) {
var originalEvent = event.originalEvent,
touches = event.touches,
eventTouches = originalEvent ? originalEvent.touches : false;
return touches && touches.length > 1 || eventTouches && eventTouches.length > 1 || null
};
var isTouchEventArgs = function(e) {
return e && e.type && e.type.indexOf('touch') === 0
};
_SlidersEventManager = rangeSelector.SlidersEventsManager = function(renderer, slidersController, processSelectionChanged) {
var that = this,
uniqueNS = that._uniqueNS = 'dx-range-selector_' + rangeSelectorCount++,
rangeSelectorEvents = rangeSelector.events;
that._renderer = renderer;
that._slidersController = slidersController;
that._processSelectionChanged = processSelectionChanged;
that._enabled = true;
that._eventsNames = {
start: addNamespace(rangeSelectorEvents.start, uniqueNS),
move: addNamespace(rangeSelectorEvents.move, uniqueNS),
end: addNamespace(rangeSelectorEvents.end, uniqueNS)
}
};
_SlidersEventManager.prototype = {
constructor: _SlidersEventManager,
_getRootOffsetLeft: function() {
return rangeSelector.utils.getRootOffsetLeft(this._renderer)
},
_initializeSliderEvents: function(sliderIndex) {
var that = this,
renderer = that._renderer,
isTouchEvent,
slidersController = that._slidersController,
processSelectionChanged = that._processSelectionChanged,
slider = slidersController.getSlider(sliderIndex),
anotherSlider = slider.getAnotherSlider(),
fastSwap,
startOffsetPosition,
splitterMoving,
sliderEndHandler = function(e) {
if (splitterMoving) {
splitterMoving = false;
slidersController.processDocking();
processSelectionChanged(false)
}
},
sliderMoveHandler = function(e) {
var doSwap,
pageX,
offsetPosition,
svgOffsetLeft = that._getRootOffsetLeft(),
position,
sliderIndex = slider.getIndex();
if (isTouchEvent !== isTouchEventArgs(e))
return;
if (!isLeftButtonPressed(e, true) && splitterMoving) {
splitterMoving = false;
slidersController.processDocking();
processSelectionChanged(false)
}
else if (splitterMoving) {
if (!isMultiTouches(e)) {
this.preventedDefault = true;
e.preventDefault()
}
pageX = getEventPageX(e);
position = pageX - startOffsetPosition - svgOffsetLeft;
offsetPosition = pageX - slider.getPosition() - svgOffsetLeft;
slidersController.moveSlider(sliderIndex, fastSwap, position, offsetPosition, startOffsetPosition, function(newStartOffsetPosition) {
startOffsetPosition = newStartOffsetPosition
});
processSelectionChanged(true)
}
},
eventsNames = that._eventsNames;
slider.startEventHandler = function(e) {
if (!that._enabled || !isLeftButtonPressed(e) || splitterMoving)
return;
fastSwap = this === slider.getSliderTracker().element;
splitterMoving = true;
isTouchEvent = isTouchEventArgs(e);
startOffsetPosition = getEventPageX(e) - slider.getPosition() - that._getRootOffsetLeft();
if (!isMultiTouches(e)) {
this.preventedDefault = true;
e.stopPropagation();
e.preventDefault()
}
};
slider.on(eventsNames.start, slider.startEventHandler);
$(document).on(eventsNames.end, sliderEndHandler).on(eventsNames.move, sliderMoveHandler);
slider.__moveEventHandler = sliderMoveHandler
},
_initializeAreaEvents: function() {
var that = this,
renderer = that._renderer,
isTouchEvent,
slidersController = that._slidersController,
processSelectionChanged = that._processSelectionChanged,
areaTracker = slidersController.getAreaTracker(),
unselectedAreaProcessing = false,
splitterMoving = false,
startPageX,
areaEndHandler = function(e) {
var pageX;
if (unselectedAreaProcessing) {
pageX = getEventPageX(e);
if (that._options.behavior.moveSelectedRangeByClick && Math.abs(startPageX - pageX) < MIN_MANUAL_SELECTING_WIDTH)
slidersController.applySelectedAreaCenterPosition(pageX - that._getRootOffsetLeft());
unselectedAreaProcessing = false;
processSelectionChanged(false)
}
},
areaMoveHandler = function(e) {
var pageX,
startPosition,
endPosition,
svgOffsetLeft = that._getRootOffsetLeft();
if (isTouchEvent !== isTouchEventArgs(e))
return;
if (unselectedAreaProcessing && !isLeftButtonPressed(e)) {
unselectedAreaProcessing = false;
processSelectionChanged(false)
}
if (unselectedAreaProcessing) {
pageX = getEventPageX(e);
if (that._options.behavior.manualRangeSelectionEnabled && Math.abs(startPageX - pageX) >= MIN_MANUAL_SELECTING_WIDTH) {
startPosition = startPageX - svgOffsetLeft;
endPosition = pageX - svgOffsetLeft;
slidersController.processManualSelection(startPosition, endPosition, e);
unselectedAreaProcessing = false;
processSelectionChanged(true)
}
}
},
eventsNames = that._eventsNames;
areaTracker.on(eventsNames.start, function(e) {
if (!that._enabled || !isLeftButtonPressed(e) || unselectedAreaProcessing)
return;
unselectedAreaProcessing = true;
isTouchEvent = isTouchEventArgs(e);
startPageX = getEventPageX(e)
});
$(document).on(eventsNames.end, areaEndHandler).on(eventsNames.move, areaMoveHandler);
that.__areaMoveEventHandler = areaMoveHandler
},
_initializeSelectedAreaEvents: function() {
var that = this,
renderer = that._renderer,
isTouchEvent,
slidersController = that._slidersController,
processSelectionChanged = that._processSelectionChanged,
selectedAreaTracker = slidersController.getSelectedAreaTracker(),
selectedAreaMoving = false,
offsetStartPosition,
selectedRangeInterval,
selectedAreaEndHandler = function(e) {
if (selectedAreaMoving) {
selectedAreaMoving = false;
slidersController.processDocking();
processSelectionChanged(false)
}
},
selectedAreaMoveHandler = function(e) {
var positionDelta,
pageX;
if (isTouchEvent !== isTouchEventArgs(e))
return;
if (selectedAreaMoving && !isLeftButtonPressed(e)) {
selectedAreaMoving = false;
slidersController.processDocking();
processSelectionChanged(false)
}
if (selectedAreaMoving) {
if (!isMultiTouches(e)) {
this.preventedDefault = true;
e.preventDefault()
}
pageX = getEventPageX(e);
positionDelta = pageX - slidersController.getSlider(START_VALUE_INDEX).getPosition() - offsetStartPosition;
slidersController.moveSliders(positionDelta, selectedRangeInterval);
processSelectionChanged(true)
}
},
eventsNames = that._eventsNames;
selectedAreaTracker.on(eventsNames.start, function(e) {
if (!that._enabled || !isLeftButtonPressed(e) || selectedAreaMoving)
return;
selectedAreaMoving = true;
isTouchEvent = isTouchEventArgs(e);
offsetStartPosition = getEventPageX(e) - slidersController.getSlider(START_VALUE_INDEX).getPosition();
selectedRangeInterval = slidersController.getSelectedRangeInterval();
if (!isMultiTouches(e)) {
this.preventedDefault = true;
e.stopPropagation();
e.preventDefault()
}
});
$(document).on(eventsNames.end, selectedAreaEndHandler).on(eventsNames.move, selectedAreaMoveHandler);
that.__selectedAreaMoveEventHandler = selectedAreaMoveHandler
},
applyOptions: function(options) {
this._options = options
},
dispose: function() {
$(document).off('.' + this._uniqueNS)
},
initialize: function() {
var that = this;
if (!that._renderer.isInitialized())
return;
that._initializeSelectedAreaEvents(that);
that._initializeAreaEvents();
that._initializeSliderEvents(START_VALUE_INDEX);
that._initializeSliderEvents(END_VALUE_INDEX)
},
setEnabled: function(enabled) {
this._enabled = enabled
}
};
rangeSelector.__setEvents = setEvents
})(jQuery, DevExpress);
/*! Module viz-rangeselector, file slider.js */
(function($, DX, undefined) {
var rangeSelector = DX.viz.rangeSelector,
utils = DX.utils;
var touchSupport = "ontouchstart" in window;
var msPointerEnabled = window.navigator.msPointerEnabled || window.navigator.pointerEnabled;
var animationOptions = {duration: 250};
var SPLITTER_WIDTH = 8,
TOUCH_SPLITTER_WIDTH = 20,
START_VALUE_INDEX = 0,
END_VALUE_INDEX = 1;
rangeSelector.Slider = rangeSelector.BaseVisualElement.inherit(function() {
return {
getText: function() {
if (this._marker)
return this._marker.getText()
},
getAvailableValues: function() {
return this._values
},
getShutter: function() {
return this._shutter
},
getMarker: function() {
return this._marker
},
_createSlider: function() {
var that = this,
sliderHandle,
sliderGroup,
sliderHandleOptions = that._options.sliderHandle;
sliderGroup = that._renderer.createGroup({'class': 'slider'});
sliderGroup.applySettings({
translateX: that._options.canvas.left,
translateY: that._options.canvas.top
});
sliderHandle = that._renderer.createLine(0, 0, 0, that._options.canvas.height, {
'class': 'dx-range-selector-slider',
strokeWidth: sliderHandleOptions.width,
stroke: sliderHandleOptions.color,
strokeOpacity: sliderHandleOptions.opacity
});
sliderHandle.append(sliderGroup);
sliderGroup.setValid = function(correct) {
sliderHandle.applySettings({stroke: correct ? that._options.sliderHandle.color : that._options.sliderMarker.invalidRangeColor})
};
sliderGroup.updateHeight = function() {
sliderHandle.applySettings({points: [0, 0, 0, that._options.canvas.height]})
};
sliderGroup.applyOptions = function(options) {
sliderHandle.applySettings(options)
};
sliderGroup.__line = sliderHandle;
return sliderGroup
},
_createSliderTracker: function() {
var that = this,
sliderHandleWidth = that._options.sliderHandle.width,
splitterWidth = SPLITTER_WIDTH < sliderHandleWidth ? sliderHandleWidth : SPLITTER_WIDTH,
sliderWidth = touchSupport || msPointerEnabled ? TOUCH_SPLITTER_WIDTH : splitterWidth,
sliderTracker,
sliderTrackerGroup;
sliderTracker = that._renderer.createRect(-sliderWidth / 2, 0, sliderWidth, that._options.canvas.height, 0, {
fill: 'grey',
stroke: 'grey',
opacity: 0.0001,
style: {cursor: 'w-resize'}
});
sliderTrackerGroup = that._renderer.createGroup({'class': 'sliderTracker'});
sliderTrackerGroup.applySettings({
translateX: 0,
translateY: that._options.canvas.top
});
sliderTracker.append(sliderTrackerGroup);
sliderTrackerGroup.updateHeight = function() {
sliderTracker.applySettings({height: that._options.canvas.height})
};
sliderTrackerGroup.__rect = sliderTracker;
return sliderTrackerGroup
},
_drawSliderTracker: function(group) {
var that = this,
sliderTracker = that._createSliderTracker();
if (sliderTracker) {
sliderTracker.append(group);
that._sliderTracker = sliderTracker
}
},
_createSliderMarker: function(options) {
return rangeSelector.rangeSelectorFactory.createSliderMarker(options)
},
_setPosition: function(position, correctByMinMaxRange) {
var that = this,
correctedPosition = that._correctPosition(position),
value = that._options.translator.untranslate(correctedPosition);
that.setValue(value, correctByMinMaxRange, false);
that._position = correctedPosition
},
_setPositionForBothSliders: function(startPosition, interval) {
var that = this,
anotherSlider,
startValue,
endValue,
endPosition,
type = that._options.scale.type,
base = that._options.scale.logarithmBase,
inverted = that._options.scale.inverted;
var getNextValue = function(value, isNegative) {
var lgPower;
if (type === 'logarithmic') {
lgPower = utils.addInterval(utils.adjustValue(utils.getLog(value, base)), interval, isNegative);
return utils.raiseTo(lgPower, base)
}
else
return utils.addInterval(value, interval, isNegative)
};
anotherSlider = that.getAnotherSlider();
startPosition = that._correctBounds(startPosition);
startValue = that._options.translator.untranslate(startPosition);
endValue = getNextValue(startValue);
if (!inverted && endValue > that._options.scale.endValue || inverted && endValue < that._options.scale.endValue) {
endValue = that._options.scale.endValue;
endPosition = that._options.canvas.left + that._options.canvas.width;
startValue = getNextValue(endValue, true);
startPosition = that._options.translator.translate(startValue)
}
else
endPosition = that._options.translator.translate(endValue);
if (that._values)
if (!inverted ? startValue < that._values[0] : startValue > that._values[that._values.length - 1]) {
startValue = that._correctBusinessValueByAvailableValues(startValue, false);
endValue = getNextValue(startValue)
}
else {
endValue = that._correctBusinessValueByAvailableValues(endValue, false);
startValue = getNextValue(endValue, true)
}
anotherSlider.setValue(endValue, undefined, false);
that.setValue(startValue, undefined, false);
that._position = startPosition;
anotherSlider._position = endPosition
},
_correctPosition: function(position) {
var that = this,
correctedPosition = that._correctInversion(position);
correctedPosition = that._correctBounds(correctedPosition);
return correctedPosition
},
_correctInversion: function(position) {
var that = this,
correctedPosition = position,
anotherSliderPosition = that.getAnotherSlider().getPosition(),
slidersInverted = that.getIndex() === START_VALUE_INDEX ? position > anotherSliderPosition : position < anotherSliderPosition;
if (slidersInverted)
correctedPosition = anotherSliderPosition;
return correctedPosition
},
_correctBounds: function(position) {
var that = this,
correctedPosition = position,
canvas = that._options.canvas;
if (position < canvas.left)
correctedPosition = canvas.left;
if (position > canvas.left + canvas.width)
correctedPosition = canvas.left + canvas.width;
return correctedPosition
},
_correctBusinessValue: function(businessValue, correctByMinMaxRange, skipCorrection) {
var that = this,
result = that._correctBusinessValueByAvailableValues(businessValue, skipCorrection);
if (correctByMinMaxRange)
result = that._correctBusinessValueByMinMaxRangeFromAnotherSlider(result);
result = that._correctBusinessValueByMinRangeFromStartEndValues(result);
return result
},
_correctBusinessValueByAvailableValues: function(businessValue, skipCorrection) {
var values = this._values;
if (!skipCorrection && values)
return rangeSelector.utils.findNearValue(values, businessValue);
return businessValue
},
_correctBusinessValueByMinMaxRangeFromAnotherSlider: function(businessValue) {
var that = this,
result = businessValue,
scale = that._options.scale,
values = that._values,
sliderIndex = that.getIndex(),
anotherBusinessValue = that.getAnotherSlider().getValue(),
isValid = true,
minValue,
maxValue;
if (!scale.inverted && sliderIndex === START_VALUE_INDEX || scale.inverted && sliderIndex === END_VALUE_INDEX) {
if (scale.maxRange)
minValue = that._addInterval(anotherBusinessValue, scale.maxRange, true);
if (scale.minRange)
maxValue = that._addInterval(anotherBusinessValue, scale.minRange, true)
}
else {
if (scale.maxRange)
maxValue = that._addInterval(anotherBusinessValue, scale.maxRange);
if (scale.minRange)
minValue = that._addInterval(anotherBusinessValue, scale.minRange)
}
if (maxValue !== undefined && result > maxValue) {
result = values ? rangeSelector.utils.findLessOrEqualValue(values, maxValue) : maxValue;
isValid = false
}
else if (minValue !== undefined && result < minValue) {
result = values ? rangeSelector.utils.findGreaterOrEqualValue(values, minValue) : minValue;
isValid = false
}
that._setValid(isValid);
return result
},
_addInterval: function(value, interval, isNegative) {
var result,
type = this._options.scale.type,
base = type === "logarithmic" && this._options.scale.logarithmBase;
if (base) {
var power = utils.addInterval(utils.getLog(value, base), interval, isNegative);
result = Math.pow(base, power)
}
else
result = utils.addInterval(value, interval, isNegative);
return result
},
_correctBusinessValueByMinRangeFromStartEndValues: function(businessValue) {
var that = this,
values = that._values,
startValue,
endValue,
isValid = true,
scale = that._options.scale,
result = businessValue;
if (scale.minRange)
if (that.getIndex() === END_VALUE_INDEX) {
startValue = that._addInterval(scale.startValue, scale.minRange, scale.inverted);
if (!scale.inverted && result < startValue || scale.inverted && result > startValue)
result = startValue
}
else if (that.getIndex() === START_VALUE_INDEX) {
endValue = that._addInterval(scale.endValue, scale.minRange, !scale.inverted);
if (!scale.inverted && result > endValue || scale.inverted && result < endValue)
result = endValue
}
return result
},
_applySliderPosition: function(position, disableAnimation) {
var that = this,
isAnimation = that._options.behavior.animationEnabled && !disableAnimation,
top = that._options.canvas.top,
slider = that._slider;
if (isAnimation || slider.inAnimation) {
slider.inAnimation = true;
slider.animate({translate: {
x: position,
y: top
}}, isAnimation ? animationOptions : {duration: 0}, function() {
slider.inAnimation = false
});
that._sliderTracker.animate({translate: {
x: position,
y: top
}}, isAnimation ? animationOptions : {duration: 0})
}
else {
that._slider.applySettings({
translateX: position,
translateY: top
});
that._sliderTracker.applySettings({
translateX: position,
translateY: top
})
}
that._sliderTracker.updateHeight();
that._slider.updateHeight()
},
_applyShutterPosition: function(position, disableAnimation) {
var that = this,
shutterSettings,
shutter = that._shutter,
isAnimation = that._options.behavior.animationEnabled && !disableAnimation,
sliderIndex = that.getIndex();
if (sliderIndex == START_VALUE_INDEX)
shutterSettings = {
x: that._options.canvas.left,
y: that._options.canvas.top,
width: position - that._options.canvas.left,
height: that._options.canvas.height
};
else if (sliderIndex == END_VALUE_INDEX)
shutterSettings = {
x: position + 1,
y: that._options.canvas.top,
width: that._options.canvas.left + that._options.canvas.width - position,
height: that._options.canvas.height
};
if (shutterSettings)
if (isAnimation || shutter.inAnimation) {
shutter.inAnimation = true;
shutter.animate(shutterSettings, isAnimation ? animationOptions : {duration: 0}, function() {
shutter.inAnimation = false
})
}
else
shutter.applySettings(shutterSettings)
},
_setValid: function(isValid) {
var that = this;
if (that._marker)
that._marker.setValid(isValid);
that._slider.setValid(isValid)
},
_setText: function(text) {
var that = this;
if (that._marker)
that._marker.setText(text)
},
ctor: function(renderer, index) {
var that = this;
that.callBase(renderer);
that._index = index
},
getIndex: function() {
return this._index
},
setAvailableValues: function(values) {
this._values = values
},
setAnotherSlider: function(slider) {
this._anotherSlider = slider
},
getAnotherSlider: function(slider) {
return this._anotherSlider
},
appendTrackers: function(group) {
var that = this;
if (that._sliderTracker)
that._sliderTracker.append(group)
},
getSliderTracker: function() {
return this._sliderTracker
},
changeLocation: function() {
var that = this;
if (that._marker)
that._marker.changeLocation();
that._index = this._index === START_VALUE_INDEX ? END_VALUE_INDEX : START_VALUE_INDEX;
that._lastPosition = null
},
setPosition: function(position, correctByMinMaxRange, selectedRangeInterval) {
var that = this,
slider;
if (selectedRangeInterval !== undefined) {
slider = that.getIndex() === START_VALUE_INDEX ? that : that.getAnotherSlider();
slider._setPositionForBothSliders(position, selectedRangeInterval)
}
else
that._setPosition(position, correctByMinMaxRange)
},
getPosition: function() {
return this._position
},
_applyOptions: function(options) {
this._lastPosition = null
},
setValue: function(value, correctByMinMaxRange, skipCorrection) {
var that = this;
if (value === undefined) {
that._value = undefined;
that._valuePosition = that._position = that.getIndex() === START_VALUE_INDEX ? that._options.canvas.left : that._options.canvas.left + that._options.canvas.width;
that._setText(rangeSelector.consts.emptySliderMarkerText)
}
else {
that._value = that._correctBusinessValue(value, correctByMinMaxRange, utils.isDefined(skipCorrection) ? !!skipCorrection : true);
that._valuePosition = that._position = that._options.translator.translate(that._value);
that._setText(rangeSelector.formatValue(that._value, that._options.sliderMarker))
}
},
getValue: function() {
return this._value
},
canSwap: function() {
var that = this,
scale = that._options.scale,
startValue,
endValue,
anotherSliderValue;
if (that._options.behavior.allowSlidersSwap) {
if (scale.minRange) {
anotherSliderValue = that.getAnotherSlider().getValue();
if (that.getIndex() === START_VALUE_INDEX) {
endValue = utils.addInterval(scale.endValue, scale.minRange, !scale.inverted);
if (!scale.inverted && anotherSliderValue > endValue || scale.inverted && anotherSliderValue < endValue)
return false
}
else {
startValue = utils.addInterval(scale.startValue, scale.minRange, scale.inverted);
if (!scale.inverted && anotherSliderValue < startValue || scale.inverted && anotherSliderValue > startValue)
return false
}
}
return true
}
return false
},
processDocking: function() {
var that = this;
that._position = that._valuePosition;
that.applyPosition(false);
that._setValid(true)
},
applyPosition: function(disableAnimation) {
var that = this,
position = that.getPosition();
if (that._lastPosition !== position) {
that._applySliderPosition(position, disableAnimation);
that._applyShutterPosition(position, disableAnimation);
that._lastPosition = position
}
},
on: function(event, handler) {
var that = this;
that._sliderTracker.on(event, handler);
if (that._marker)
that._marker.getTracker().on(event, handler)
},
_update: function() {
var that = this;
that._marker && that._marker.applyOptions(that._options.sliderMarker);
that._shutter && that._shutter.applySettings({
fill: that._options.shutter.color,
fillOpacity: that._options.shutter.opacity
});
that._slider && that._slider.applyOptions({
strokeWidth: that._options.sliderHandle.width,
stroke: that._options.sliderHandle.color,
strokeOpacity: that._options.sliderHandle.opacity
})
},
_draw: function(group) {
var that = this,
slider,
marker,
sliderAreaGroup,
shutter,
startPos,
startWidth,
index = that.getIndex();
sliderAreaGroup = that._renderer.createGroup({'class': 'sliderArea'});
sliderAreaGroup.append(group);
if (index === START_VALUE_INDEX)
shutter = that._renderer.createRect(that._options.canvas.left, that._options.canvas.top, 0, that._options.canvas.height, 0);
else if (index === END_VALUE_INDEX)
shutter = that._renderer.createRect(that._options.canvas.left, that._options.canvas.top, that._options.canvas.width, that._options.canvas.height, 0);
if (shutter) {
shutter.append(sliderAreaGroup);
slider = that._createSlider();
if (slider)
slider.append(sliderAreaGroup);
if (that._options.sliderMarker.visible) {
marker = that._createSliderMarker({
renderer: that._renderer,
isLeftPointer: index === END_VALUE_INDEX,
sliderMarkerOptions: that._options.sliderMarker
});
marker.draw(slider)
}
that._shutter = shutter;
that._slider = slider;
that._marker = marker
}
that._drawSliderTracker(group)
}
}
}())
})(jQuery, DevExpress);
/*! Module viz-rangeselector, file sliderMarker.js */
(function($, DX, undefined) {
var rangeSelector = DX.viz.rangeSelector,
_SliderMarker;
_SliderMarker = rangeSelector.SliderMarker = function(options) {
var that = this;
that._renderer = options.renderer;
that._text = options.text;
that._isLeftPointer = options.isLeftPointer;
that._options = options.sliderMarkerOptions;
that._isValid = true;
initializeAreaPoints(that, {
width: 10,
height: 10
})
};
var applyOptions = function(options) {
this._options = options;
this.update()
};
var getRectSize = function(that, textSize) {
return {
width: Math.round(2 * that._options.padding + textSize.width),
height: Math.round(2 * that._options.padding + textSize.height * rangeSelector.consts.fontHeightRatio)
}
};
var initializeAreaPoints = function(that, textSize) {
var rectSize = getRectSize(that, textSize);
that._points = [];
if (that._isLeftPointer) {
that._points.push({
x: 0,
y: 0
});
that._points.push({
x: rectSize.width,
y: 0
});
that._points.push({
x: rectSize.width,
y: rectSize.height
});
that._points.push({
x: that._options.pointerSize,
y: rectSize.height
});
that._points.push({
x: 0,
y: rectSize.height + that._options.pointerSize
})
}
else {
that._points.push({
x: 0,
y: 0
});
that._points.push({
x: rectSize.width,
y: 0
});
that._points.push({
x: rectSize.width,
y: rectSize.height + that._options.pointerSize
});
that._points.push({
x: rectSize.width - that._options.pointerSize,
y: rectSize.height
});
that._points.push({
x: 0,
y: rectSize.height
})
}
};
var getPointerPosition = function(that, textSize) {
var rectSize = getRectSize(that, textSize);
if (that._isLeftPointer)
return {
x: 0,
y: rectSize.height + that._options.pointerSize
};
else
return {
x: rectSize.width - 1,
y: rectSize.height + that._options.pointerSize
}
};
var draw = function(group) {
var that = this;
var padding = that._options.padding;
that._sliderMarkerGroup = that._renderer.createGroup({'class': 'sliderMarker'});
that._sliderMarkerGroup.append(group);
that._area = that._renderer.createArea(that.points, {fill: that._options.color});
that._area.append(that._sliderMarkerGroup);
that._label = that._renderer.createText(that._text, padding, padding, {
font: that._options.font,
align: 'left',
style: {'-webkit-user-select': 'none'}
});
that._label.append(that._sliderMarkerGroup);
that._tracker = that._renderer.createRect(0, 0, 2 * padding, 2 * padding + that._options.pointerSize, 0, {
fill: 'grey',
stroke: 'grey',
opacity: 0.0001,
style: {cursor: 'pointer'}
});
that._tracker.append(that._sliderMarkerGroup);
that._drawn = true;
that.update()
};
var getTextSize = function(that) {
var textSize = that._label.getBBox();
if (!that._textHeight && isFinite(textSize.height))
that._textHeight = textSize.height;
return {
width: textSize.width,
height: that._textHeight
}
};
var update = function(stop) {
var that = this,
textSize,
rectSize,
pointerPosition;
that._interval && clearInterval(that._interval);
delete that._interval;
if (!that._drawn)
return;
that._label.updateText(that._text);
textSize = getTextSize(that);
if (!stop) {
that._textSize = that._textSize || textSize;
that._textSize = textSize.width > that._textSize.width || textSize.height > that._textSize.height ? textSize : that._textSize;
textSize = that._textSize;
that._interval = setInterval(function() {
update.call(that, [true])
}, 75)
}
else {
delete that._textSize;
that._textSize = textSize
}
rectSize = getRectSize(that, textSize);
pointerPosition = getPointerPosition(that, textSize);
that._sliderMarkerGroup.applySettings({
translateX: -pointerPosition.x,
translateY: -pointerPosition.y
});
initializeAreaPoints(that, textSize);
that._area.applySettings({
points: that._points,
fill: that._isValid ? that._options.color : that._options.invalidRangeColor
});
that._tracker.applySettings({
width: rectSize.width,
height: rectSize.height + that._options.pointerSize
});
that._label.applySettings({
x: that._options.padding,
y: rectSize.height - that._options.padding
})
};
var getText = function() {
var that = this;
return that._text
};
var setText = function(value) {
var that = this;
if (that._text !== value) {
that._text = value;
that.update()
}
};
var setValid = function(isValid) {
var that = this;
that._isValid = isValid;
that.update()
};
var changeLocation = function() {
var that = this;
that._isLeftPointer = !that._isLeftPointer;
that.update()
};
var getTracker = function() {
var that = this;
return that._tracker
};
_SliderMarker.prototype = {
constructor: _SliderMarker,
draw: draw,
update: update,
getText: getText,
setText: setText,
changeLocation: changeLocation,
applyOptions: applyOptions,
getTracker: getTracker,
setValid: setValid
}
})(jQuery, DevExpress);
/*! Module viz-rangeselector, file rangeView.js */
(function($, DX, undefined) {
var rangeSelector = DX.viz.rangeSelector;
rangeSelector.RangeView = rangeSelector.BaseVisualElement.inherit(function() {
return {_draw: function(group) {
var that = this,
viewRect,
viewImage,
backgroundColor,
series,
i,
showChart,
canvas,
options = that._options,
seriesOptions,
isEmpty = options.isEmpty;
showChart = options.seriesDataSource && options.seriesDataSource.isShowChart() && !isEmpty;
canvas = options.canvas;
if (showChart)
backgroundColor = options.seriesDataSource.getBackgroundColor();
else if (!isEmpty && options.background.visible)
backgroundColor = options.background.color;
if (options.background.visible && backgroundColor) {
viewRect = that._renderer.createRect(canvas.left, canvas.top, canvas.width + 1, canvas.height, 0, {
fill: backgroundColor,
'class': 'dx-range-selector-background'
});
viewRect.append(group)
}
if (options.background.visible && options.background.image && options.background.image.url) {
viewImage = that._renderer.createImage(canvas.left, canvas.top, canvas.width + 1, canvas.height, options.background.image.url, {location: options.background.image.location});
viewImage.append(group)
}
if (showChart) {
series = options.seriesDataSource.getSeries();
options.seriesDataSource.adjustSeriesDimensions(options.translators, options.chart.useAggregation);
for (i = 0; i < series.length; i++) {
seriesOptions = series[i].getOptions();
seriesOptions.seriesGroup = group;
seriesOptions.labelsGroup = group;
series[i].draw(options.translators, options.behavior && options.behavior.animationEnabled && that._renderer.animationEnabled())
}
}
}}
}())
})(jQuery, DevExpress);
/*! Module viz-rangeselector, file seriesDataSource.js */
(function($, DX, undefined) {
var rangeSelector = DX.viz.rangeSelector,
charts = DX.viz.charts,
core = DX.viz.core,
coreFactory = core.CoreFactory,
utils = DX.utils;
rangeSelector.SeriesDataSource = DX.Class.inherit(function() {
var createThemeManager = function(chartOptions) {
return charts.factory.createThemeManager(chartOptions, 'rangeSelector.chart')
};
var isArrayOfSimpleTypes = function(data) {
return $.isArray(data) && data.length > 0 && (utils.isNumber(data[0]) || utils.isDate(data[0]))
};
var convertToArrayOfObjects = function(data) {
return $.map(data, function(item, i) {
return {
arg: item,
val: i
}
})
};
var calculateSeries = function(that, options, templatedSeries) {
var series = [],
particularSeriesOptions,
seriesTheme,
data,
parsedData,
chartThemeManager = that.themeManager,
hasSeriesTemplate = !!chartThemeManager.getOptions('seriesTemplate'),
allSeriesOptions = hasSeriesTemplate ? templatedSeries : options.chart.series,
seriesValueType = options.chart.valueAxis && options.chart.valueAxis.valueType,
dataSourceField,
i;
that.teamplateData = [];
if (options.dataSource && !allSeriesOptions) {
if (isArrayOfSimpleTypes(options.dataSource))
options.dataSource = convertToArrayOfObjects(options.dataSource);
dataSourceField = options.dataSourceField || 'arg';
allSeriesOptions = {
argumentField: dataSourceField,
valueField: dataSourceField
};
that._hideChart = true
}
allSeriesOptions = $.isArray(allSeriesOptions) ? allSeriesOptions : allSeriesOptions ? [allSeriesOptions] : [];
that._backgroundColor = options.backgroundColor !== undefined ? options.backgroundColor : chartThemeManager.getOptions("backgroundColor");
for (i = 0; i < allSeriesOptions.length; i++) {
particularSeriesOptions = $.extend(true, {
argumentType: options.valueType,
argumentAxisType: options.axisType,
valueType: dataSourceField ? options.valueType : seriesValueType,
incidentOccured: options.incidentOccured
}, allSeriesOptions[i]);
particularSeriesOptions.rotated = false;
data = particularSeriesOptions.data || options.dataSource;
seriesTheme = chartThemeManager.getOptions("series", particularSeriesOptions);
seriesTheme.argumentField = seriesTheme.argumentField || options.dataSourceField;
if (data && data.length > 0) {
var newSeries = coreFactory.createSeries(options.renderer, seriesTheme);
series.push(newSeries)
}
if (hasSeriesTemplate) {
$.each(data, function(_, data) {
$.each(newSeries.getTeamplatedFields(), function(_, field) {
data[field.teamplateField] = data[field.originalField]
});
that.teamplateData.push(data)
});
newSeries.updateTeamplateFieldNames()
}
}
data = hasSeriesTemplate ? that.teamplateData : data;
that._dataValidator = charts.factory.createDataValidator(data, [series], options.incidentOccured, chartThemeManager.getOptions("dataPrepareSettings"));
parsedData = that._dataValidator.validate();
for (i = 0; i < series.length; i++) {
var particularSeries = series[i];
particularSeries.updateData(parsedData)
}
return series
};
var processSeriesFamilies = function(series, equalBarWidth, minBubbleSize, maxBubbleSize) {
var families = [],
types = [];
$.each(series, function(i, item) {
if ($.inArray(item.type, types) === -1)
types.push(item.type)
});
$.each(types, function(_, type) {
var family = new coreFactory.createSeriesFamily({
type: type,
equalBarWidth: equalBarWidth,
minBubbleSize: minBubbleSize,
maxBubbleSize: maxBubbleSize
});
family.add(series);
family.adjustSeriesValues();
families.push(family)
});
return families
};
var prototypeObject = {
ctor: function(options) {
var that = this,
templatedSeries,
seriesTemplate,
themeManager = that.themeManager = createThemeManager(options.chart),
topIndent = themeManager.getOptions('topIndent'),
bottomIndent = themeManager.getOptions('bottomIndent');
that._indent = {
top: topIndent >= 0 && topIndent < 1 ? topIndent : 0,
bottom: bottomIndent >= 0 && bottomIndent < 1 ? bottomIndent : 0
};
that._valueAxis = themeManager.getOptions('valueAxisRangeSelector') || {};
that._hideChart = false;
seriesTemplate = themeManager.getOptions('seriesTemplate');
if (options.dataSource && seriesTemplate)
templatedSeries = utils.processSeriesTemplate(seriesTemplate, options.dataSource);
that._series = calculateSeries(that, options, templatedSeries);
that._seriesFamilies = processSeriesFamilies(that._series, themeManager.getOptions('equalBarWidth'), themeManager.getOptions('minBubbleSize'), themeManager.getOptions('maxBubbleSize'))
},
adjustSeriesDimensions: function(translators, useAggregation) {
var that = this;
if (useAggregation)
$.each(that._series || [], function(_, s) {
s.resamplePoints(translators)
});
$.each(that._seriesFamilies, function() {
this.adjustSeriesDimensions(translators)
})
},
getBoundRange: function() {
var that = this,
rangeData,
valueAxisMin = that._valueAxis.min,
valueAxisMax = that._valueAxis.max,
valRange = new core.Range({
isValueRange: true,
min: valueAxisMin,
minVisible: valueAxisMin,
max: valueAxisMax,
maxVisible: valueAxisMax,
axisType: that._valueAxis.type,
base: that._valueAxis.logarithmBase
}),
argRange = new core.Range({}),
rangeYSize,
rangeVisibleSizeY,
i,
minIndent,
maxIndent;
for (i = 0; i < that._series.length; i++) {
rangeData = that._series[i].getRangeData();
valRange.addRange(rangeData.val);
argRange.addRange(rangeData.arg)
}
if (valRange.isDefined() && argRange.isDefined()) {
minIndent = that._valueAxis.inverted ? that._indent.top : that._indent.bottom;
maxIndent = that._valueAxis.inverted ? that._indent.bottom : that._indent.top;
rangeYSize = valRange.max - valRange.min;
rangeVisibleSizeY = ($.isNumeric(valRange.maxVisible) ? valRange.maxVisible : valRange.max) - ($.isNumeric(valRange.minVisible) ? valRange.minVisible : valRange.min);
if (utils.isDate(valRange.min))
valRange.min = new Date(valRange.min.valueOf() - rangeYSize * minIndent);
else
valRange.min -= rangeYSize * minIndent;
if (utils.isDate(valRange.max))
valRange.max = new Date(valRange.max.valueOf() + rangeYSize * maxIndent);
else
valRange.max += rangeYSize * maxIndent;
if ($.isNumeric(rangeVisibleSizeY)) {
valRange.maxVisible = valRange.maxVisible ? valRange.maxVisible + rangeVisibleSizeY * maxIndent : undefined;
valRange.minVisible = valRange.minVisible ? valRange.minVisible - rangeVisibleSizeY * minIndent : undefined
}
valRange.invert = that._valueAxis.inverted
}
return {
arg: argRange,
val: valRange
}
},
getSeries: function() {
var that = this;
return that._series
},
getBackgroundColor: function() {
var that = this;
return that._backgroundColor
},
isEmpty: function() {
var that = this;
return that.getSeries().length === 0
},
isShowChart: function() {
var that = this;
return !that.isEmpty() && !that._hideChart
},
getCalculatedValueType: function() {
var that = this,
result;
if (that._series.length)
result = that._series[0].argumentType;
return result
}
};
return prototypeObject
}())
})(jQuery, DevExpress);
/*! Module viz-rangeselector, file themeManager.js */
(function($, DX, undefined) {
DX.viz.rangeSelector = DX.viz.rangeSelector;
DX.viz.rangeSelector.ThemeManager = DX.viz.core.BaseThemeManager.inherit({
_themeSection: 'rangeSelector',
ctor: function(userTheme) {
this.setTheme(userTheme)
},
_initializeTheme: function() {
this._initializeFont(this._theme.scale.label.font);
this._initializeFont(this._theme.sliderMarker.font);
this._initializeFont(this._theme.loadingIndicator.font)
},
applyRangeSelectorTheme: function(userOptions) {
var that = this,
chart = userOptions.chart,
dataSource = userOptions.dataSource,
result;
delete userOptions.dataSource;
delete userOptions.chart;
result = $.extend(true, {}, that._theme, userOptions);
result.dataSource = dataSource;
if (chart)
result.chart = chart;
return result
},
setBackgroundColor: function(containerBackgroundColor) {
var theme = this._theme;
if (containerBackgroundColor)
theme.containerBackgroundColor = containerBackgroundColor;
theme.shutter.color = theme.shutter.color || theme.containerBackgroundColor
}
})
})(jQuery, DevExpress);
/*! Module viz-rangeselector, file dxRangeSelector.js */
(function($, DX, undefined) {
var ui = DX.ui,
viz = DX.viz;
DX.registerComponent("dxRangeSelector", viz.rangeSelector.RangeSelector)
})(jQuery, DevExpress);
DevExpress.MOD_VIZ_RANGESELECTOR = true
}
if (!DevExpress.MOD_VIZ_VECTORMAP) {
if (!DevExpress.MOD_VIZ_CORE)
throw Error('Required module is not referenced: viz-core');
/*! Module viz-vectormap, file map.js */
(function(DX, $, undefined) {
DX.viz.map = {};
var _Number = window.Number,
_isFunction = DX.utils.isFunction,
_getRootOffset = DX.utils.getRootOffset;
var DEFAULT_WIDTH = 800,
DEFAULT_HEIGHT = 400;
var DATA_KEY = DX.viz.map.__DATA_KEY = 'vectormap-data';
DX.viz.map.Map = DX.viz.core.BaseWidget.inherit({
_init: function() {
var that = this;
that.callBase.apply(that, arguments);
that.renderer = that._renderer = that._factory.createRenderer({
width: 1,
height: 1,
pathModified: that.option('pathModified'),
rtl: that.option('rtlEnabled')
});
that.renderer.draw(that._element().get(0));
that._root = that._renderer.getRoot();
that._root.applySettings({
'class': 'dxm',
stroke: 'none',
strokeWidth: 0,
fill: 'none',
align: 'center',
cursor: 'default',
style: {overflow: 'hidden'}
});
that._themeManager = that._factory.createThemeManager();
that._projection = that._factory.createProjection();
that._tracker = that._factory.createTracker({root: that._root});
that._background = that._renderer.createRect(0, 0, 0, 0, 0, {'class': 'dxm-background'}).data(DATA_KEY, {type: 'background'});
that._areasManager = that._factory.createAreasManager({
container: that._root,
renderer: that._renderer,
projection: that._projection,
themeManager: that._themeManager,
tracker: that._tracker,
ready: function() {
that.hideLoadingIndicator()
}
});
that._areasManager.setData(that.option('mapData'));
that._markersManager = that._factory.createMarkersManager({
container: that._root,
renderer: that._renderer,
projection: that._projection,
themeManager: that._themeManager,
tracker: that._tracker
});
that._markersManager.setData(that.option('markers'));
that._controlBar = that._factory.createControlBar({
container: that._root,
renderer: that._renderer,
context: that,
resetCallback: controlResetCallback,
beginMoveCallback: controlBeginMoveCallback,
endMoveCallback: controlEndMoveCallback,
moveCallback: controlMoveCallback,
zoomCallback: controlZoomCallback
});
that._legend = that._factory.createLegend({
container: that._root,
renderer: that._renderer,
themeManager: that._themeManager
});
that._tooltip = that._factory.createTooltip({
container: that._root,
renderer: that._renderer,
tracker: that._tracker
});
that._projection.setBounds(that.option('bounds')).setMaxZoom(that.option('maxZoomFactor')).setZoom(that.option('zoomFactor')).setCenter(that.option('center'));
that._themeManager.setTheme(that.option('theme'));
that._themeManager.patchRtlSettings(that.option('rtlEnabled'));
that._setClickCallback(that.option('click'));
that._setCenterChangedCallback(that.option('centerChanged'));
that._setZoomFactorChangedCallback(that.option('zoomFactorChanged'));
that._setTrackerCallbacks()
},
_dispose: function() {
var that = this;
that.callBase.apply(that, arguments);
that._resetTrackerCallbacks();
that._themeManager.dispose();
that._tracker.dispose();
that._areasManager.dispose();
that._markersManager.dispose();
that._controlBar.dispose();
that._legend.dispose();
that._tooltip.dispose();
that._renderer.dispose();
that._disposeLoadIndicator();
that._renderer = that._themeManager = that._projection = that._tracker = that._root = that._background = that._areasManager = that._markersManager = that._controlBar = that._legend = that._tooltip = that._centerChangedCallback = that._zoomFactorChangedCallback = null
},
_setTrackerCallbacks: function() {
var that = this,
renderer = that._renderer,
managers = {
area: that._areasManager,
marker: that._markersManager
},
projection = that._projection,
controlBar = that._controlBar,
tooltip = that._tooltip,
xdrag,
ydrag,
isControlDrag = false;
that._tracker.setCallbacks({
click: function(arg) {
var offset = _getRootOffset(renderer);
arg.$event.x = arg.x - offset.left;
arg.$event.y = arg.y - offset.top;
var manager = managers[arg.data.type];
if (manager)
manager.raiseClick(arg.data.index, arg.$event);
if (manager || arg.data.type === 'background')
that._raiseClick(arg.$event)
},
start: function(arg) {
isControlDrag = arg.data.type === 'control-bar';
if (isControlDrag) {
arg.data = arg.data.index;
controlBar.processStart(arg)
}
else {
xdrag = arg.x;
ydrag = arg.y;
projection.snapCenter()
}
},
move: function(arg) {
if (isControlDrag) {
arg.data = arg.data.index;
controlBar.processMove(arg)
}
else {
projection.moveCenter(xdrag - arg.x, ydrag - arg.y);
xdrag = arg.x;
ydrag = arg.y;
that._applyTranslate()
}
},
end: function(arg) {
if (isControlDrag) {
arg.data = arg.data.index;
controlBar.processEnd(arg)
}
else
projection.isCenterChanged() && that._raiseCenterChanged();
isControlDrag = false
},
zoom: function(arg) {
controlBar.processZoom(arg)
},
'hover-on': function(arg) {
var manager = managers[arg.data.type];
if (manager)
manager.hoverItem(arg.data.index, true)
},
'hover-off': function(arg) {
var manager = managers[arg.data.type];
if (manager)
manager.hoverItem(arg.data.index, false)
},
'focus-on': function(arg, done) {
var result = false;
if (tooltip.enabled()) {
var proxy = managers[arg.data.type] ? managers[arg.data.type].getProxyItem(arg.data.index) : null;
if (!!proxy && tooltip.prepare(proxy, {offset: 12})) {
var offset = _getRootOffset(renderer);
tooltip.show().move(arg.x - offset.left, arg.y - offset.top);
result = true
}
}
done(result)
},
'focus-move': function(arg) {
var offset = _getRootOffset(renderer);
tooltip.move(arg.x - offset.left, arg.y - offset.top)
},
'focus-off': function(arg) {
tooltip.hide()
}
});
that._resetTrackerCallbacks = function() {
that._resetTrackerCallbacks = that = renderer = managers = projection = controlBar = tooltip = null
}
},
_adjustSize: function(force) {
var that = this,
size = that.option('size') || {},
width = size.width >= 0 ? _Number(size.width) : that._element().width(),
height = size.height >= 0 ? _Number(size.height) : that._element().height(),
hidden = false;
if (width === 0)
if (_Number(size.width) === 0)
hidden = true;
else
width = DEFAULT_WIDTH;
if (height === 0)
if (_Number(size.height) === 0)
hidden = true;
else
height = DEFAULT_HEIGHT;
if (hidden || !that._element().is(':visible')) {
that._incidentOccured("W2001", [that.NAME]);
that._width = that._height = 0;
return false
}
var needResize = that._width !== width || that._height !== height || force;
if (needResize) {
that._width = width;
that._height = height;
that._renderer.resize(width, height);
that._projection.setSize(width, height);
that._legend.applyLayout(width, height);
that._tooltip.setSize(width, height);
that._background.applySettings({
x: 0,
y: 0,
width: width,
height: height
});
that._applyTranslate();
that._updateLoadIndicator(undefined, width, height)
}
return needResize
},
_clean: function() {
var that = this;
that._tracker.clean();
that._background.detach();
that._areasManager.clean();
that._markersManager.clean();
that._controlBar.clean();
that._legend.clean();
that._tooltip.clean()
},
_render: function() {
var that = this;
if (!that._adjustSize(true))
return;
that._tooltip.update(that._themeManager.getTooltipSettings(that.option('tooltip')));
that._tracker.setOptions(that.option('interaction') || {});
that._controlBar.setZoomPartition(that._projection.getZoomScalePartition()).setZoom(that._projection.getScaledZoom()).setOptions(that._themeManager.getControlBarSettings(that.option('controlBar')), that.option('interaction'));
that._background.applySettings(that._themeManager.getBackgroundSettings(that.option('background')));
that._background.append(that._root);
that._areasManager.render(that.option('areaSettings'));
that._markersManager.render(that.option('markerSettings'));
that._controlBar.render();
that._legend.render(that._themeManager.getLegendSettings(that.option('legend')));
that._tooltip.render();
that._tracker.render();
that._drawn()
},
_optionChanged: function(name, value) {
var that = this;
switch (name) {
case'theme':
that._themeManager.setTheme(value);
that._themeManager.patchRtlSettings(that.option('rtlEnabled'));
that._invalidate();
break;
case'click':
that._setClickCallback(value);
break;
case'centerChanged':
that._setCenterChangedCallback(value);
break;
case'zoomFactorChanged':
that._setZoomFactorChangedCallback(value);
break;
case'mapData':
that._areasManager.setData(value);
break;
case'markers':
that._markersManager.setData(value);
break;
case'bounds':
that._projection.setBounds(value);
that._invalidate();
break;
case'maxZoomFactor':
that._projection.setMaxZoom(value);
that._invalidate();
break;
case'zoomFactor':
that._updateZoomFactor(value);
break;
case'center':
that._updateCenter(value);
break;
default:
that.callBase.apply(that, arguments);
break
}
},
_getLoadIndicatorOption: function() {
return this._themeManager.getLoadIndicatorSettings(this.option('loadingIndicator'))
},
_setClickCallback: function(callback) {
this._clickCallback = _isFunction(callback) ? callback : null
},
_setCenterChangedCallback: function(callback) {
var that = this;
that._centerChangedCallback = _isFunction(callback) ? function() {
that._centerChangedCallback && callback.call(that, that._projection.getCenter())
} : null
},
_setZoomFactorChangedCallback: function(callback) {
var that = this;
that._zoomFactorChangedCallback = _isFunction(callback) ? function() {
that._zoomFactorChangedCallback && callback.call(that, that._projection.getZoom())
} : null
},
_raiseClick: function(arg) {
var that = this;
that._clickCallback && setTimeout(function() {
that._clickCallback && that._clickCallback.call(that, arg)
}, 0)
},
_raiseCenterChanged: function() {
this._centerChangedCallback && setTimeout(this._centerChangedCallback, 0)
},
_raiseZoomFactorChanged: function() {
this._zoomFactorChangedCallback && setTimeout(this._zoomFactorChangedCallback, 0)
},
_updateCenter: function(center, _noEvent) {
this._projection.snapCenter().setCenter(center);
if (this._projection.isCenterChanged()) {
this._applyTransform();
_noEvent || this._raiseCenterChanged()
}
},
_updateZoomFactor: function(zoomFactor, _noEvent) {
var that = this;
that._projection.snapZoom().setZoom(zoomFactor);
if (that._projection.isZoomChanged()) {
that._controlBar.setZoom(that._projection.getScaledZoom());
that._applyTransform(true);
_noEvent || that._raiseZoomFactorChanged()
}
},
_updateViewport: function(viewport, _noEvent) {
var that = this;
that._projection.snapCenter().snapZoom().setViewport(viewport);
that._applyTransform(that._projection.isZoomChanged());
if (that._projection.isCenterChanged())
_noEvent || that._raiseCenterChanged();
if (that._projection.isZoomChanged()) {
that._controlBar.setZoom(that._projection.getScaledZoom());
_noEvent || that._raiseZoomFactorChanged()
}
},
_resize: function() {
if (this._adjustSize())
this._applyTransform(true)
},
_applyTranslate: function() {
var transform = this._projection.getTransform();
this._areasManager.transform(transform);
this._markersManager.transform(transform)
},
_applyTransform: function(redraw, _noTrackerReset) {
_noTrackerReset || this._tracker.reset();
this._applyTranslate();
if (redraw) {
this._areasManager.redraw();
this._markersManager.redraw()
}
},
_refresh: function() {
var that = this,
callBase = that.callBase;
that._endLoading(function() {
callBase.call(that)
})
},
render: function() {
var that = this;
if (that._width === 0 && that._height === 0)
that._refresh();
else
that._resize();
return that
},
getAreas: function() {
return this._areasManager.getProxyItems()
},
getMarkers: function() {
return this._markersManager.getProxyItems()
},
clearAreaSelection: function(_noEvent) {
this._areasManager.clearSelection(_noEvent);
return this
},
clearMarkerSelection: function(_noEvent) {
this._markersManager.clearSelection(_noEvent);
return this
},
clearSelection: function(_noEvent) {
return this.clearAreaSelection(_noEvent).clearMarkerSelection(_noEvent)
},
center: function(value, _noEvent) {
if (value === undefined)
return this._projection.getCenter();
else {
this._updateCenter(value, _noEvent);
return this
}
},
zoomFactor: function(value, _noEvent) {
if (value === undefined)
return this._projection.getZoom();
else {
this._updateZoomFactor(value, _noEvent);
return this
}
},
viewport: function(value, _noEvent) {
if (value === undefined)
return this._projection.getViewport();
else {
this._updateViewport(value, _noEvent);
return this
}
},
convertCoordinates: function(x, y) {
return this._projection.fromScreenPointStrict(x, y)
},
showLoadingIndicator: function() {
this._showLoadIndicator(this._themeManager.getLoadIndicatorSettings(this.option('loadingIndicator')), {
width: this._width,
height: this._height
})
},
_factory: {
createRenderer: function(options) {
return new DX.viz.renderers.Renderer(options)
},
createTooltip: function(parameters) {
return new Tooltip(parameters)
},
createLegend: function(parameters) {
return new Legend(parameters)
}
}
});
var Tooltip = DX.viz.core.Tooltip.inherit({
ctor: function(parameters) {
var that = this;
that._container = parameters.container;
that._root = parameters.renderer.createGroup({'class': 'dxm-tooltip'});
that.callBase(null, that._root, parameters.renderer);
that._tracker = parameters.tracker;
that._enabled = false
},
dispose: function() {
var that = this;
that._container = that._root = that._tracker = null;
return that.callBase.apply(that, arguments)
},
clean: function() {
this._root.detach();
return this
},
render: function() {
this._root.append(this._container);
return this
}
});
var Legend = DX.viz.core.Legend.inherit({
ctor: function(parameters) {
var that = this;
that._container = parameters.container;
that._root = parameters.renderer.createGroup({'class': 'dxm-legend'});
that._themeManager = parameters.themeManager;
that.callBase(null, null, parameters.renderer, that._root)
},
dispose: function() {
var that = this;
that._container = that._root = that._themeManager = null;
return that.callBase.apply(that, arguments)
},
clean: function() {
this._root.detach();
return this
},
render: function(options) {
var that = this,
items = [],
i = 0,
ii = options.items ? options.items.length : 0;
for (; i < ii; ++i)
items.push(that._themeManager.getLegendItemSettings(options.items[i] || {}));
that.update(items, options);
that._root.append(that._container);
return that.applyLayout(that._size.width, that._size.height)
},
applyLayout: function(width, height) {
var that = this,
layoutOptions;
that.setSize({
width: width,
height: height
});
that.draw();
layoutOptions = that.getLayoutOptions();
if (layoutOptions) {
var left,
top;
if (layoutOptions.horizontalAlignment === 'left')
left = 0;
else if (layoutOptions.horizontalAlignment === 'center')
left = width / 2 - layoutOptions.width / 2;
else
left = width - layoutOptions.width;
if (layoutOptions.verticalAlignment === 'top')
top = 0;
else
top = height - layoutOptions.height;
that.shift(left, top)
}
return that
}
});
function projectAreaDefault(dataItem) {
return this._projection.projectArea(dataItem.coordinates)
}
function projectAreaGeoJson(dataItem) {
if (dataItem.geometry) {
var type = dataItem.geometry.type,
coordinates = dataItem.geometry.coordinates;
if (coordinates && (type === 'Polygon' || type === 'MultiPolygon')) {
type === 'MultiPolygon' && (coordinates = [].concat.apply([], coordinates));
return this._projection.projectArea(coordinates)
}
}
return []
}
function controlResetCallback() {
var projection = this._projection,
isCenterChanged,
isZoomChanged;
projection.snapCenter().snapZoom().setCenter(null).setZoom(null);
isCenterChanged = projection.isCenterChanged();
isZoomChanged = projection.isZoomChanged();
if (isCenterChanged || isZoomChanged)
this._applyTransform(isZoomChanged, true);
isCenterChanged && this._raiseCenterChanged();
isZoomChanged && this._raiseZoomFactorChanged()
}
function controlBeginMoveCallback() {
this._projection.snapCenter()
}
function controlEndMoveCallback() {
this._projection.isCenterChanged() && this._raiseCenterChanged()
}
function controlMoveCallback(dx, dy) {
this._projection.moveCenter(dx, dy);
this._applyTranslate()
}
function controlZoomCallback(zoom, x, y) {
var that = this,
keepPosition = x !== undefined && y !== undefined,
coords,
screenPosition;
if (keepPosition) {
screenPosition = _getRootOffset(that._renderer);
screenPosition = [x - screenPosition.left, y - screenPosition.top];
coords = that._projection.fromScreenPoint(screenPosition[0], screenPosition[1])
}
that._projection.snapZoom().setScaledZoom(zoom);
if (that._projection.isZoomChanged()) {
keepPosition && that._projection.snapCenter().setCenterByPoint(coords, screenPosition);
that._applyTransform(true, true);
that._raiseZoomFactorChanged();
keepPosition && that._projection.isCenterChanged() && that._raiseCenterChanged()
}
}
DX.registerComponent('dxVectorMap', DX.viz.map.Map);
DX.viz.map._internal = {};
DX.viz.map.sources = {};
DX.viz.map._tests = {};
DX.viz.map._tests.Legend = Legend;
DX.viz.map._tests.Tooltip = Tooltip
})(DevExpress, jQuery);
/*! Module viz-vectormap, file projection.js */
(function(DX, $, undefined) {
var _Number = Number,
_isFinite = isFinite,
_min = Math.min,
_max = Math.max,
_abs = Math.abs,
_tan = Math.tan,
_atan = Math.atan,
_exp = Math.exp,
_round = Math.round,
_ln = Math.log,
_pow = Math.pow,
_isArray = DX.utils.isArray,
_buildPath = DX.viz.renderers.buildPath;
var PI = Math.PI,
QUARTER_PI = PI / 4,
PI_TO_360 = PI / 360,
TWO_TO_LN2 = 2 / Math.LN2;
var DEFAULT_MIN_ZOOM = 1,
DEFAULT_MAX_ZOOM = 1 << 8;
var MERCATOR_MIN_LON = -180,
MERCATOR_MAX_LON = 180,
MERCATOR_MIN_LAT = -85.0511,
MERCATOR_MAX_LAT = 85.0511;
var mercator = {
aspectRatio: 1,
project: function(coordinates) {
var lon = coordinates[0],
lat = coordinates[1];
return [lon <= MERCATOR_MIN_LON ? -1 : lon >= MERCATOR_MAX_LON ? +1 : lon / 180, lat <= MERCATOR_MIN_LAT ? +1 : lat >= MERCATOR_MAX_LAT ? -1 : -_ln(_tan(QUARTER_PI + lat * PI_TO_360)) / PI]
},
unproject: function(coordinates) {
var x = coordinates[0],
y = coordinates[1];
return [x <= -1 ? MERCATOR_MIN_LON : x >= +1 ? MERCATOR_MAX_LON : 180 * x, y <= -1 ? MERCATOR_MAX_LAT : y >= +1 ? MERCATOR_MIN_LAT : (_atan(_exp(-PI * coordinates[1])) - QUARTER_PI) / PI_TO_360]
}
};
function createProjectUnprojectMethods(p1, p2, delta) {
var x0 = (p1[0] + p2[0]) / 2 - delta / 2,
y0 = (p1[1] + p2[1]) / 2 - delta / 2,
k = 2 / delta;
return {
project: function(coordinates) {
var p = mercator.project(coordinates);
return [-1 + (p[0] - x0) * k, -1 + (p[1] - y0) * k]
},
unproject: function(coordinates) {
var p = [x0 + (coordinates[0] + 1) / k, y0 + (coordinates[1] + 1) / k];
return mercator.unproject(p)
}
}
}
function floatsEqual(f1, f2) {
return _abs(f1 - f2) < 1E-8
}
function truncate(value, min, max, fallback) {
var _value = _Number(value);
if (_value < min)
_value = min;
else if (_value > max)
_value = max;
else if (!(min <= _value && _value <= max))
_value = fallback;
return _value
}
function truncateQuad(quad, min, max) {
return {
lt: [truncate(quad[0], min[0], max[0], min[0]), truncate(quad[1], min[1], max[1], min[1])],
rb: [truncate(quad[2], min[0], max[0], max[0]), truncate(quad[3], min[1], max[1], max[1])]
}
}
function parseBounds(bounds) {
var p1 = mercator.unproject([-1, -1]),
p2 = mercator.unproject([+1, +1]),
min = [_min(p1[0], p2[0]), _min(p1[1], p2[1])],
max = [_max(p1[0], p2[0]), _max(p1[1], p2[1])],
quad = bounds;
if (quad && quad.minLon)
quad = [quad.minLon, quad.minLat, quad.maxLon, quad.maxLat];
if (quad)
quad = truncateQuad(quad, min, max);
return {
minBase: min,
maxBase: max,
min: quad ? [_min(quad.lt[0], quad.rb[0]), _min(quad.lt[1], quad.rb[1])] : min,
max: quad ? [_max(quad.lt[0], quad.rb[0]), _max(quad.lt[1], quad.rb[1])] : max
}
}
function selectCenterValue(value1, value2, center1, center2) {
var result;
if (value1 > -1 && value2 >= +1)
result = center1;
else if (value1 <= -1 && value2 < +1)
result = center2;
else
result = (center1 + center2) / 2;
return result
}
function Projection() {
this.setBounds(null)
}
Projection.prototype = {
constructor: Projection,
_minZoom: DEFAULT_MIN_ZOOM,
_maxZoom: DEFAULT_MAX_ZOOM,
_zoom: DEFAULT_MIN_ZOOM,
setSize: function(width, height) {
var that = this;
that._x0 = width / 2;
that._y0 = height / 2;
if (width / height <= mercator.aspectRatio) {
that._xradius = width / 2;
that._yradius = width / 2 / mercator.aspectRatio
}
else {
that._xradius = height / 2 * mercator.aspectRatio;
that._yradius = height / 2
}
return that
},
setBounds: function(bounds) {
var that = this,
_bounds = parseBounds(bounds);
that._minBase = _bounds.minBase;
that._maxBase = _bounds.maxBase;
that._minBound = _bounds.min;
that._maxBound = _bounds.max;
var p1 = mercator.project(_bounds.min),
p2 = mercator.project(_bounds.max),
delta = _min(truncate(_abs(p2[0] - p1[0]), 0.1, 2, 2), truncate(_abs(p2[1] - p1[1]), 0.1, 2, 2)),
methods = delta < 2 ? createProjectUnprojectMethods(p1, p2, delta) : mercator;
that._project = methods.project;
that._unproject = methods.unproject;
var minv = that._project(_bounds.minBase),
maxv = that._project(_bounds.maxBase);
that._minv = [_min(minv[0], maxv[0]), _min(minv[1], maxv[1])];
that._maxv = [_max(minv[0], maxv[0]), _max(minv[1], maxv[1])];
that._defaultCenter = that._unproject([0, 0]);
return that.setCenter(that._defaultCenter)
},
_toScreen: function(coordinates) {
return [this._x0 + this._xradius * coordinates[0], this._y0 + this._yradius * coordinates[1]]
},
_fromScreen: function(coordinates) {
return [(coordinates[0] - this._x0) / this._xradius, (coordinates[1] - this._y0) / this._yradius]
},
_toTransformed: function(coordinates) {
return [coordinates[0] * this._zoom + this._dxcenter, coordinates[1] * this._zoom + this._dycenter, ]
},
_toTransformedFast: function(coordinates) {
return [coordinates[0] * this._zoom, coordinates[1] * this._zoom]
},
_fromTransformed: function(coordinates) {
return [(coordinates[0] - this._dxcenter) / this._zoom, (coordinates[1] - this._dycenter) / this._zoom]
},
_adjustCenter: function() {
var that = this,
center = that._project(that._center);
that._dxcenter = -center[0] * that._zoom;
that._dycenter = -center[1] * that._zoom
},
projectArea: function(coordinates) {
var i = 0,
ii = _isArray(coordinates) ? coordinates.length : 0,
subcoords,
j,
jj,
subresult,
result = [];
for (; i < ii; ++i) {
subcoords = coordinates[i];
subresult = [];
for (j = 0, jj = _isArray(subcoords) ? subcoords.length : 0; j < jj; ++j)
subresult.push(this._project(subcoords[j]));
result.push(subresult)
}
return result
},
projectPoint: function(coordinates) {
return coordinates ? this._project(coordinates) : []
},
getAreaCoordinates: function(data) {
var k = 0,
kk = data.length,
partialData,
i,
ii,
list = [],
partialPath,
point;
for (; k < kk; ++k) {
partialData = data[k];
partialPath = [];
for (i = 0, ii = partialData.length; i < ii; ++i) {
point = this._toScreen(this._toTransformedFast(partialData[i]));
partialPath.push(point[0], point[1])
}
list.push(_buildPath(partialPath))
}
return list.join(' ')
},
getPointCoordinates: function(data) {
var point = this._toScreen(this._toTransformedFast(data));
return {
x: _round(point[0]),
y: _round(point[1])
}
},
getZoom: function() {
return this._zoom
},
setZoom: function(zoom) {
var that = this;
that._zoom = truncate(zoom, that._minZoom, that._maxZoom, that._minZoom);
that._adjustCenter();
return that
},
getScaledZoom: function() {
return _round((this._scale.length - 1) * _ln(this._zoom) / _ln(this._maxZoom))
},
setScaledZoom: function(scaledZoom) {
return this.setZoom(this._scale[_round(scaledZoom)])
},
getZoomScalePartition: function() {
return this._scale.length - 1
},
_setupScaling: function() {
var that = this,
k = _round(TWO_TO_LN2 * _ln(that._maxZoom));
k = k > 4 ? k : 4;
var step = _pow(that._maxZoom, 1 / k),
zoom = that._minZoom,
i = 1;
that._scale = [zoom];
for (; i <= k; ++i)
that._scale.push(zoom *= step)
},
setMaxZoom: function(maxZoom) {
var that = this;
that._minZoom = DEFAULT_MIN_ZOOM;
that._maxZoom = truncate(maxZoom, that._minZoom, _Number.MAX_VALUE, DEFAULT_MAX_ZOOM);
that._setupScaling();
if (that._zoom > that._maxZoom)
that.setZoom(that._maxZoom);
return that
},
getMinZoom: function() {
return this._minZoom
},
getMaxZoom: function() {
return this._maxZoom
},
getCenter: function() {
return [this._center[0], this._center[1]]
},
setCenter: function(center) {
var _center = _isArray(center) ? center : null;
_center = _center || center && (center.lon || center.lat) && [center.lon, center.lat] || [];
var that = this;
that._center = [truncate(_center[0], that._minBound[0], that._maxBound[0], that._defaultCenter[0]), truncate(_center[1], that._minBound[1], that._maxBound[1], that._defaultCenter[1])];
that._adjustCenter();
return that
},
setCenterByPoint: function(coordinates, screenPosition) {
var that = this,
p = that._project(coordinates),
q = that._fromScreen(screenPosition);
return that.setCenter(that._unproject([-q[0] / that._zoom + p[0], -q[1] / that._zoom + p[1]]))
},
moveCenter: function(screenDx, screenDy) {
var that = this,
current = that._toScreen(that._toTransformed(that._project(that._center))),
center = that._unproject(that._fromTransformed(that._fromScreen([current[0] + screenDx, current[1] + screenDy])));
return that.setCenter(center)
},
getViewport: function() {
var p1 = this._unproject(this._fromTransformed([-1, -1])),
p2 = this._unproject(this._fromTransformed([+1, +1]));
return [p1[0], p1[1], p2[0], p2[1]]
},
setViewport: function(viewport) {
var that = this;
if (!_isArray(viewport))
return that.setZoom(that._minZoom).setCenter(that._defaultCenter);
var _viewport = truncateQuad(viewport, that._minBase, that._maxBase),
lt = that._project(_viewport.lt),
rb = that._project(_viewport.rb),
l = _min(lt[0], rb[0]),
t = _min(lt[1], rb[1]),
r = _max(lt[0], rb[0]),
b = _max(lt[1], rb[1]),
zoom = 2 / _max(r - l, b - t),
xc = selectCenterValue(l, r, -1 - zoom * l, +1 - zoom * r),
yc = selectCenterValue(t, b, -1 - zoom * t, +1 - zoom * b);
return that.setZoom(zoom).setCenter(that._unproject([-xc / zoom, -yc / zoom]))
},
getTransform: function() {
return {
translateX: this._dxcenter * this._xradius,
translateY: this._dycenter * this._yradius
}
},
fromScreenPoint: function(x, y) {
return this._unproject(this._fromTransformed(this._fromScreen([x, y])))
},
fromScreenPointStrict: function(x, y) {
var that = this,
p = that._fromTransformed(that._fromScreen([x, y])),
q = that._unproject(p);
return [p[0] >= that._minv[0] && p[0] <= that._maxv[0] ? q[0] : NaN, p[1] >= that._minv[1] && p[1] <= that._maxv[1] ? q[1] : NaN]
},
snapCenter: function() {
this._snappedCenter = this.getCenter();
return this
},
isCenterChanged: function() {
var center = this.getCenter();
return !floatsEqual(this._snappedCenter[0], center[0]) || !floatsEqual(this._snappedCenter[1], center[1])
},
snapZoom: function() {
this._snappedZoom = this.getZoom();
return this
},
isZoomChanged: function() {
return !floatsEqual(this._snappedZoom, this.getZoom())
}
};
DX.viz.map._tests.Projection = Projection;
DX.viz.map._tests.mercator = mercator;
DX.viz.map._tests._DEBUG_stubMercator = function(stub) {
mercator = stub
};
DX.viz.map._tests._DEBUG_restoreMercator = function() {
mercator = DX.viz.map._tests.mercator
};
DX.viz.map.Map.prototype._factory.createProjection = function() {
return new Projection
}
})(DevExpress, jQuery);
/*! Module viz-vectormap, file controlBar.js */
(function(DX, undefined) {
var _buildPath = DX.viz.renderers.buildPath,
_setTimeout = setTimeout,
_clearTimeout = clearTimeout,
_round = Math.round,
_pow = Math.pow,
_ln = Math.log;
var _LN2 = Math.LN2;
var COMMAND_RESET = 'command-reset',
COMMAND_MOVE_UP = 'command-move-up',
COMMAND_MOVE_RIGHT = 'command-move-right',
COMMAND_MOVE_DOWN = 'command-move-down',
COMMAND_MOVE_LEFT = 'command-move-left',
COMMAND_ZOOM_IN = 'command-zoom-in',
COMMAND_ZOOM_OUT = 'command-zoom-out',
COMMAND_ZOOM_DRAG = 'command-zoom-drag';
var _DATA_KEY = DX.viz.map.__DATA_KEY,
EVENT_TARGET_TYPE = 'control-bar';
var COMMAND_TO_TYPE_MAP = {};
COMMAND_TO_TYPE_MAP[COMMAND_RESET] = ResetCommand;
COMMAND_TO_TYPE_MAP[COMMAND_MOVE_UP] = COMMAND_TO_TYPE_MAP[COMMAND_MOVE_RIGHT] = COMMAND_TO_TYPE_MAP[COMMAND_MOVE_DOWN] = COMMAND_TO_TYPE_MAP[COMMAND_MOVE_LEFT] = MoveCommand;
COMMAND_TO_TYPE_MAP[COMMAND_ZOOM_IN] = COMMAND_TO_TYPE_MAP[COMMAND_ZOOM_OUT] = ZoomCommand;
COMMAND_TO_TYPE_MAP[COMMAND_ZOOM_DRAG] = ZoomDragCommand;
var ControlBar = DX.Class.inherit({
ctor: function(parameters) {
var that = this;
that._container = parameters.container;
that._createElements(parameters.renderer);
var context = parameters.context,
resetCallback = parameters.resetCallback,
beginMoveCallback = parameters.beginMoveCallback,
endMoveCallback = parameters.endMoveCallback,
moveCallback = parameters.moveCallback,
zoomCallback = parameters.zoomCallback;
parameters = null;
that._reset = function() {
resetCallback.call(context)
};
that._beginMove = function() {
beginMoveCallback.call(context)
};
that._endMove = function() {
endMoveCallback.call(context)
};
that._move = function(dx, dy) {
moveCallback.call(context, dx, dy)
};
that._zoom = function(zoom, x, y) {
zoomCallback.call(context, zoom, x, y)
};
that._dispose = function() {
this._reset = this._move = this._zoom = this._dispose = context = resetCallback = moveCallback = zoomCallback = null
}
},
_createElements: function(renderer) {
var that = this;
that._root = renderer.createGroup({'class': 'dxm-control-bar'});
that._buttonsGroup = renderer.createGroup({'class': 'dxm-control-buttons'}).append(that._root);
that._trackersGroup = renderer.createGroup({
stroke: 'none',
strokeWidth: 0,
fill: '#000000',
opacity: 0.0001,
cursor: 'pointer'
}).append(that._root);
var options = {
bigCircleSize: 58,
smallCircleSize: 28,
buttonSize: 10,
arrowButtonOffset: 20,
incdecButtonSize: 11,
incButtonOffset: 66,
decButtonOffset: 227,
sliderLineStartOffset: 88.5,
sliderLineEndOffset: 205.5,
sliderLength: 20,
sliderWidth: 8,
trackerGap: 4
};
that._createButtons(renderer, options);
that._createTrackers(renderer, options);
that._root.applySettings({
translateX: 50.5,
translateY: 50.5
})
},
_createButtons: function(renderer, options) {
var group = this._buttonsGroup,
size = options.buttonSize / 2,
offset1 = options.arrowButtonOffset - size,
offset2 = options.arrowButtonOffset,
incdecButtonSize = options.incdecButtonSize / 2;
renderer.createCircle(0, 0, options.bigCircleSize / 2).append(group);
renderer.createCircle(0, 0, size).append(group);
renderer.createPath([-size, -offset1, 0, -offset2, size, -offset1]).append(group);
renderer.createPath([offset1, -size, offset2, 0, offset1, size]).append(group);
renderer.createPath([size, offset1, 0, offset2, -size, offset1]).append(group);
renderer.createPath([-offset1, size, -offset2, 0, -offset1, -size]).append(group);
renderer.createCircle(0, options.incButtonOffset, options.smallCircleSize / 2).append(group);
renderer.createSimplePath({d: _buildPath([-incdecButtonSize, options.incButtonOffset, incdecButtonSize, options.incButtonOffset]) + ' ' + _buildPath([0, options.incButtonOffset - incdecButtonSize, 0, options.incButtonOffset + incdecButtonSize])}).append(group);
renderer.createCircle(0, options.decButtonOffset, options.smallCircleSize / 2).append(group);
renderer.createSimplePath({d: _buildPath([-incdecButtonSize, options.decButtonOffset, incdecButtonSize, options.decButtonOffset])}).append(group);
renderer.createSimplePath({d: _buildPath([0, options.sliderLineStartOffset, 0, options.sliderLineEndOffset])}).append(group);
this._zoomDrag = renderer.createRect(-options.sliderLength / 2, options.sliderLineEndOffset - options.sliderWidth / 2, options.sliderLength, options.sliderWidth).append(group);
this._sliderLineLength = options.sliderLineEndOffset - options.sliderLineStartOffset
},
_createTrackers: function(renderer, options) {
var group = this._trackersGroup,
size = _round((options.arrowButtonOffset - options.trackerGap) / 2),
offset1 = options.arrowButtonOffset - size,
offset2 = _round(_pow(options.bigCircleSize * options.bigCircleSize / 4 - size * size, 0.5)),
size2 = offset2 - offset1,
element;
renderer.createRect(-size, -size, size * 2, size * 2).append(group).data(_DATA_KEY, {
index: COMMAND_RESET,
type: EVENT_TARGET_TYPE
});
renderer.createRect(-size, -offset2, size * 2, size2).append(group).data(_DATA_KEY, {
index: COMMAND_MOVE_UP,
type: EVENT_TARGET_TYPE
});
renderer.createRect(offset1, -size, size2, size * 2).append(group).data(_DATA_KEY, {
index: COMMAND_MOVE_RIGHT,
type: EVENT_TARGET_TYPE
});
renderer.createRect(-size, offset1, size * 2, size2).append(group).data(_DATA_KEY, {
index: COMMAND_MOVE_DOWN,
type: EVENT_TARGET_TYPE
});
renderer.createRect(-offset2, -size, size2, size * 2).append(group).data(_DATA_KEY, {
index: COMMAND_MOVE_LEFT,
type: EVENT_TARGET_TYPE
});
renderer.createCircle(0, options.incButtonOffset, options.smallCircleSize / 2).append(group).data(_DATA_KEY, {
index: COMMAND_ZOOM_IN,
type: EVENT_TARGET_TYPE
});
renderer.createCircle(0, options.decButtonOffset, options.smallCircleSize / 2).append(group).data(_DATA_KEY, {
index: COMMAND_ZOOM_OUT,
type: EVENT_TARGET_TYPE
});
this._zoomDragCover = renderer.createRect(-options.sliderLength / 2, options.sliderLineEndOffset - options.sliderWidth / 2, options.sliderLength, options.sliderWidth).append(group).data(_DATA_KEY, {
index: COMMAND_ZOOM_DRAG,
type: EVENT_TARGET_TYPE
})
},
dispose: function() {
var that = this;
delete that._container;
that._dispose();
that._root.clear();
delete that._root;
delete that._buttonsGroup;
delete that._zoomDrag;
delete that._zoomDragCover;
return that
},
setZoomPartition: function(partition) {
this._zoomPartition = partition;
this._sliderUnitLength = this._sliderLineLength / partition;
return this
},
setZoom: function(zoom) {
this._adjustZoom(zoom);
return this
},
setOptions: function(options, interactionOptions) {
options = options || {};
interactionOptions = interactionOptions || {};
this._dragAndZoomEnabled = interactionOptions.dragAndZoomEnabled !== undefined ? !!interactionOptions.dragAndZoomEnabled : true;
this._enabled = this._dragAndZoomEnabled && (options.enabled !== undefined ? !!options.enabled : true);
this._buttonsGroup.applySettings(options.shape);
return this
},
clean: function() {
this._enabled && this._root.detach();
return this
},
render: function() {
this._enabled && this._root.append(this._container);
return this
},
_adjustZoom: function(zoom) {
var that = this;
that._zoomFactor = _round(zoom);
that._zoomFactor >= 0 || (that._zoomFactor = 0);
that._zoomFactor <= that._zoomPartition || (that._zoomFactor = that._zoomPartition);
var transform = {translateY: -that._zoomFactor * that._sliderUnitLength};
that._zoomDrag.applySettings(transform);
that._zoomDragCover.applySettings(transform)
},
_applyZoom: function(x, y) {
this._zoom(this._zoomFactor, x, y)
},
processStart: function(arg) {
if (this._dragAndZoomEnabled) {
var commandType = COMMAND_TO_TYPE_MAP[arg.data];
this._command = new commandType(this, arg)
}
return this
},
processMove: function(arg) {
if (this._dragAndZoomEnabled)
this._command.update(arg);
return this
},
processEnd: function(arg) {
if (this._dragAndZoomEnabled)
this._command.finish(arg);
return this
},
processZoom: function(arg) {
var that = this,
zoomFactor;
if (that._dragAndZoomEnabled) {
if (arg.delta)
zoomFactor = arg.delta;
else if (arg.ratio)
zoomFactor = _ln(arg.ratio) / _LN2;
that._adjustZoom(that._zoomFactor + zoomFactor);
that._applyZoom(arg.x, arg.y)
}
return that
}
});
function disposeCommand(command) {
delete command._owner;
command.update = function(){};
command.finish = function(){}
}
function ResetCommand(owner, arg) {
this._owner = owner;
this._command = arg.data
}
ResetCommand.prototype.update = function(arg) {
arg.data !== this._command && disposeCommand(this)
};
ResetCommand.prototype.finish = function() {
this._owner._reset();
this._owner._adjustZoom(0);
disposeCommand(this)
};
function MoveCommand(owner, arg) {
this._command = arg.data;
var timeout = null,
interval = 100,
dx = 0,
dy = 0;
switch (this._command) {
case COMMAND_MOVE_UP:
dy = -10;
break;
case COMMAND_MOVE_RIGHT:
dx = 10;
break;
case COMMAND_MOVE_DOWN:
dy = 10;
break;
case COMMAND_MOVE_LEFT:
dx = -10;
break
}
function callback() {
owner._move(dx, dy);
timeout = _setTimeout(callback, interval)
}
this._stop = function() {
_clearTimeout(timeout);
owner._endMove();
this._stop = owner = callback = null;
return this
};
arg = null;
owner._beginMove();
callback()
}
MoveCommand.prototype.update = function(arg) {
this._command !== arg.data && this.finish()
};
MoveCommand.prototype.finish = function() {
disposeCommand(this._stop())
};
function ZoomCommand(owner, arg) {
this._owner = owner;
this._command = arg.data;
var timeout = null,
interval = 150,
dzoom = this._command === COMMAND_ZOOM_IN ? 1 : -1;
function callback() {
owner._adjustZoom(owner._zoomFactor + dzoom);
timeout = _setTimeout(callback, interval)
}
this._stop = function() {
_clearTimeout(timeout);
this._stop = owner = callback = null;
return this
};
arg = null;
callback()
}
ZoomCommand.prototype.update = function(arg) {
this._command !== arg.data && this.finish()
};
ZoomCommand.prototype.finish = function() {
this._owner._applyZoom();
disposeCommand(this._stop())
};
function ZoomDragCommand(owner, arg) {
this._owner = owner;
this._zoomFactor = owner._zoomFactor;
this._pos = arg.y
}
ZoomDragCommand.prototype.update = function(arg) {
var owner = this._owner;
owner._adjustZoom(this._zoomFactor + owner._zoomPartition * (this._pos - arg.y) / owner._sliderLineLength)
};
ZoomDragCommand.prototype.finish = function() {
this._owner._applyZoom();
disposeCommand(this)
};
DX.viz.map._tests.ControlBar = ControlBar;
DX.viz.map.Map.prototype._factory.createControlBar = function(parameters) {
return new ControlBar(parameters)
}
})(DevExpress);
/*! Module viz-vectormap, file tracker.js */
(function(DX, $, undefined) {
var _addNamespace = DX.ui.events.addNamespace,
_abs = Math.abs,
_sqrt = Math.sqrt,
_round = Math.round,
_max = Math.max,
_min = Math.min,
_now = $.now,
_extend = $.extend;
var _NAME = DX.viz.map.Map.prototype.NAME,
_DATA_KEY = DX.viz.map.__DATA_KEY;
var $doc = $(document);
var EVENTS = {};
setupEvents();
var EVENT_START = 'start',
EVENT_MOVE = 'move',
EVENT_END = 'end',
EVENT_ZOOM = 'zoom',
EVENT_HOVER_ON = 'hover-on',
EVENT_HOVER_OFF = 'hover-off',
EVENT_CLICK = 'click',
EVENT_FOCUS_ON = 'focus-on',
EVENT_FOCUS_MOVE = 'focus-move',
EVENT_FOCUS_OFF = 'focus-off';
var CLICK_TIME_THRESHOLD = 500,
CLICK_COORD_THRESHOLD = 5,
DRAG_COORD_THRESHOLD_MOUSE = 5,
DRAG_COORD_THRESHOLD_TOUCH = 10,
FOCUS_ON_DELAY_MOUSE = 300,
FOCUS_OFF_DELAY_MOUSE = 300,
FOCUS_ON_DELAY_TOUCH = 300,
FOCUS_OFF_DELAY_TOUCH = 400,
FOCUS_COORD_THRESHOLD_MOUSE = 5;
function Tracker(parameters) {
this._root = parameters.root;
this._callbacks = {};
this._createEventHandlers();
this._focus = new Focus(this._callbacks)
}
_extend(Tracker.prototype, {
dispose: function() {
var that = this;
that._focus.dispose();
that._root = that._callbacks = that._focus = that._rootClickEvents = that._$docClickEvents = that._rootZoomEvents = that._$docZoomEvents = that._rootHoverEvents = that._$docHoverEvents = that._rootFocusEvents = that._$docFocusEvents = null;
return that
},
_createEventHandlers: function() {
var that = this;
that._rootClickEvents = {};
that._rootClickEvents[EVENTS.start] = function(event) {
var isTouch = isTouchEvent(event);
if (isTouch && !that._isTouchEnabled)
return;
event.preventDefault();
var coords = getEventCoords(event);
that._clickState = {
x: coords.x,
y: coords.y,
time: _now()
}
};
that._$docClickEvents = {};
that._$docClickEvents[EVENTS.end] = function(event) {
var state = that._clickState;
if (!state)
return;
var isTouch = isTouchEvent(event);
if (isTouch && !that._isTouchEnabled)
return;
if (_now() - state.time <= CLICK_TIME_THRESHOLD) {
var coords = getEventCoords(event);
if (_abs(coords.x - state.x) <= CLICK_COORD_THRESHOLD && _abs(coords.y - state.y) <= CLICK_COORD_THRESHOLD)
that._callbacks[EVENT_CLICK]({
data: $(event.target).data(_DATA_KEY) || {},
x: coords.x,
y: coords.y,
$event: event
})
}
that._clickState = null
};
that._rootDragEvents = {};
that._rootDragEvents[EVENTS.start] = function(event) {
var isTouch = isTouchEvent(event);
if (isTouch && !that._isTouchEnabled)
return;
var coords = getEventCoords(event);
that._dragState = {
x: coords.x,
y: coords.y,
data: $(event.target).data(_DATA_KEY) || {}
};
if (that._isDragEnabled)
that._callbacks[EVENT_START]({
data: that._dragState.data,
x: coords.x,
y: coords.y
})
};
that._$docDragEvents = {};
that._$docDragEvents[EVENTS.move] = function(event) {
var state = that._dragState;
if (!state)
return;
var isTouch = isTouchEvent(event);
if (isTouch && !that._isTouchEnabled)
return;
var coords = getEventCoords(event),
threshold = isTouch ? DRAG_COORD_THRESHOLD_TOUCH : DRAG_COORD_THRESHOLD_MOUSE;
if (state.active || _abs(coords.x - state.x) > threshold || _abs(coords.y - state.y) > threshold) {
state.x = coords.x;
state.y = coords.y;
state.active = true;
state.data = $(event.target).data(_DATA_KEY) || {};
if (that._isDragEnabled)
that._callbacks[EVENT_MOVE]({
data: state.data,
x: coords.x,
y: coords.y
})
}
};
that._$docDragEvents[EVENTS.end] = function(event) {
var state = that._dragState;
if (!state)
return;
var isTouch = isTouchEvent(event);
if (isTouch && !that._isTouchEnabled)
return;
that._endDragging()
};
that._rootZoomEvents = {};
that._rootZoomEvents[EVENTS.wheel] = function(event) {
if (!that._isWheelEnabled)
return;
event.preventDefault();
if (that._zoomState)
return;
var delta = event.originalEvent.wheelDelta / 120 || event.originalEvent.detail / -3 || 0;
if (delta === 0)
return;
delta = delta > 0 ? _min(_round(delta) || +1, +4) : _max(_round(delta) || -1, -4);
var coords = getEventCoords(event);
if (that._isZoomEnabled)
that._callbacks[EVENT_ZOOM]({
delta: delta,
x: coords.x,
y: coords.y
});
that._zoomState = setTimeout(function() {
that._zoomState = null
}, 50)
};
that._rootZoomEvents[EVENTS.start] = function(event) {
var isTouch = isTouchEvent(event);
if (!isTouch || !that._isTouchEnabled)
return;
var state = that._zoomState = that._zoomState || {};
if (state.pointer1 && state.pointer2)
return;
var coords;
if (state.pointer1 === undefined) {
state.pointer1 = getPointerId(event) || 0;
coords = getMultitouchEventCoords(event, state.pointer1);
state.x1 = state.x1_0 = coords.x;
state.y1 = state.y1_0 = coords.y
}
if (state.pointer2 === undefined) {
var pointer2 = getPointerId(event) || 1;
if (pointer2 !== state.pointer1) {
coords = getMultitouchEventCoords(event, pointer2);
if (coords) {
state.x2 = state.x2_0 = coords.x;
state.y2 = state.y2_0 = coords.y;
state.pointer2 = pointer2;
state.ready = true;
that._endDragging()
}
}
}
};
that._$docZoomEvents = {};
that._$docZoomEvents[EVENTS.move] = function(event) {
var state = that._zoomState;
if (!state)
return;
var isTouch = isTouchEvent(event);
if (!isTouch || !that._isTouchEnabled)
return;
var coords;
if (state.pointer1 !== undefined) {
coords = getMultitouchEventCoords(event, state.pointer1);
if (coords) {
state.x1 = coords.x;
state.y1 = coords.y
}
}
if (state.pointer2 !== undefined) {
coords = getMultitouchEventCoords(event, state.pointer2);
if (coords) {
state.x2 = coords.x;
state.y2 = coords.y
}
}
};
that._$docZoomEvents[EVENTS.end] = function(event) {
var state = that._zoomState;
if (!state)
return;
var isTouch = isTouchEvent(event);
if (!isTouch || !that._isTouchEnabled)
return;
if (state.ready) {
var startDistance = getDistance(state.x1_0, state.y1_0, state.x2_0, state.y2_0),
currentDistance = getDistance(state.x1, state.y1, state.x2, state.y2);
if (that._isZoomEnabled)
that._callbacks[EVENT_ZOOM]({
ratio: currentDistance / startDistance,
x: (state.x1_0 + state.x2_0) / 2,
y: (state.y1_0 + state.y2_0) / 2
})
}
that._zoomState = null
};
that._rootHoverEvents = {};
that._rootHoverEvents[EVENTS.over] = function(event) {
if (that._hoverTarget === event.target)
return;
var isTouch = isTouchEvent(event);
if (isTouch)
return;
var data = $(event.target).data(_DATA_KEY);
if (!data)
return;
that._hoverTarget && that._endHovering();
that._hoverTarget = event.target;
that._hoverState = {data: data};
that._callbacks[EVENT_HOVER_ON]({data: data})
};
that._$docHoverEvents = {};
that._$docHoverEvents[EVENTS.out] = function(event) {
var state = that._hoverState;
if (!state)
return;
var isTouch = isTouchEvent(event);
if (isTouch)
return;
var data = $(event.target).data(_DATA_KEY);
if (!data)
return;
that._endHovering()
};
that._rootFocusEvents = {};
that._rootFocusEvents[EVENTS.start] = function(event) {
var isTouch = isTouchEvent(event);
if (!isTouch || !that._isTouchEnabled)
return;
var data = $(event.target).data(_DATA_KEY);
if (!data)
return;
that._focus.turnOff(FOCUS_OFF_DELAY_TOUCH);
that._focus.turnOn(event.target, data, getEventCoords(event), FOCUS_ON_DELAY_TOUCH);
that._skip$docEvent = true
};
that._rootFocusEvents[EVENTS.over] = function(event) {
if (that._focusTarget === event.target)
return;
that._focusTarget = event.target;
var isTouch = isTouchEvent(event);
if (isTouch)
return;
var data = $(event.target).data(_DATA_KEY);
if (!data)
return;
if (that._focusTarget)
that._focus.turnOff(FOCUS_OFF_DELAY_MOUSE);
var coords = getEventCoords(event);
if (that._focus.active)
that._focus.move(event.target, data, coords);
else
that._focus.turnOn(event.target, data, coords, FOCUS_ON_DELAY_MOUSE)
};
that._$docFocusEvents = {};
that._$docFocusEvents[EVENTS.start] = function(event) {
that._focusTarget = event.target;
var isTouch = isTouchEvent(event);
if (!isTouch || !that._isTouchEnabled)
return;
if (!that._skip$docEvent)
that._focus.turnOff(FOCUS_OFF_DELAY_TOUCH);
that._skip$docEvent = null
};
that._$docFocusEvents[EVENTS.move] = function(event) {
if (that._focus.disabled)
return;
if (that._focusTarget !== event.target)
return;
var isTouch = isTouchEvent(event);
if (isTouch && !that._isTouchEnabled)
return;
var data = $(event.target).data(_DATA_KEY);
if (!data)
return;
var coords = getEventCoords(event);
if (isTouch) {
if (that._dragState && that._dragState.active || that._zoomState && that._zoomState.ready)
that._focus.cancel()
}
else if (that._focus.active)
if (that._dragState && that._dragState.active) {
that._focus.cancel();
that._focus.turnOn(event.target, data, coords, FOCUS_ON_DELAY_MOUSE * 4)
}
else
that._focus.move(event.target, data, coords);
else if (_abs(coords.x - that._focus.x) > FOCUS_COORD_THRESHOLD_MOUSE || _abs(coords.y - that._focus.y) > FOCUS_COORD_THRESHOLD_MOUSE)
that._focus.turnOn(event.target, data, coords, FOCUS_ON_DELAY_MOUSE)
};
that._$docFocusEvents[EVENTS.end] = function(event) {
if (that._focus.disabled)
return;
var isTouch = isTouchEvent(event);
if (!isTouch || !that._isTouchEnabled)
return;
that._focusTarget = null;
if (!that._focus.active)
that._focus.turnOff(FOCUS_OFF_DELAY_TOUCH);
else if (that._focus.changing)
that._focus.cancel()
};
that._$docFocusEvents[EVENTS.out] = function(event) {
if (that._focus.disabled)
return;
var isTouch = isTouchEvent(event);
if (isTouch)
return;
that._focusTarget = null;
var data = $(event.target).data(_DATA_KEY);
if (!data)
return;
that._focus.turnOff(FOCUS_OFF_DELAY_MOUSE)
}
},
_endDragging: function() {
var that = this,
state = that._dragState;
that._dragState = null;
if (state && that._isDragEnabled)
that._callbacks[EVENT_END]({
data: state.data,
x: state.x,
y: state.y
})
},
_endHovering: function() {
var that = this,
state = that._hoverState;
that._hoverState = that._hoverTarget = null;
if (state)
that._callbacks[EVENT_HOVER_OFF]({data: state.data})
},
reset: function() {
var that = this;
that._clickState = null;
that._endDragging();
that._endHovering();
that._focus.cancel();
that._focusTarget = null;
return that
},
setCallbacks: function(callbacks) {
_extend(this._callbacks, callbacks);
return this
},
setOptions: function(options) {
this._isTouchEnabled = options.touchEnabled === undefined || !!options.touchEnabled;
this._isWheelEnabled = options.wheelEnabled === undefined || !!options.wheelEnabled;
this._isDragEnabled = options.dragAndZoomEnabled === undefined || !!options.dragAndZoomEnabled;
this._isZoomEnabled = options.dragAndZoomEnabled === undefined || !!options.dragAndZoomEnabled;
return this
},
clean: function() {
var that = this;
if (that._isTouchEnabled) {
that._root.applySettings({style: {
'touch-action': '',
'-ms-touch-action': '',
'-webkit-user-select': ''
}});
that._root.off(_addNamespace('MSHoldVisual', _NAME)).off(_addNamespace('contextmenu', _NAME))
}
that._detachEventHandlers();
that.reset();
return that
},
render: function() {
var that = this;
if (that._isTouchEnabled) {
that._root.applySettings({style: {
'touch-action': 'none',
'-ms-touch-action': 'none',
'-webkit-user-select': 'none'
}});
that._root.on(_addNamespace('MSHoldVisual', _NAME), function(event) {
event.preventDefault()
}).on(_addNamespace('contextmenu', _NAME), function(event) {
isTouchEvent(event) && event.preventDefault()
})
}
that._attachEventHandlers();
return that
},
_attachEventHandlers: function() {
var that = this;
that._root.on(that._rootClickEvents).on(that._rootDragEvents).on(that._rootZoomEvents).on(that._rootHoverEvents).on(that._rootFocusEvents);
$doc.on(that._$docClickEvents).on(that._$docDragEvents).on(that._$docZoomEvents).on(that._$docHoverEvents).on(that._$docFocusEvents)
},
_detachEventHandlers: function() {
var that = this;
that._root.off(that._rootClickEvents).off(that._rootDragEvents).off(that._rootZoomEvents).off(that._rootHoverEvents).off(that._rootFocusEvents);
$doc.off(that._$docClickEvents).off(that._$docDragEvents).off(that._$docZoomEvents).off(that._$docHoverEvents).off(that._$docFocusEvents)
}
});
function Focus(callbacks) {
this._callbacks = callbacks;
this.disabled = true
}
_extend(Focus.prototype, {
dispose: function() {
var that = this;
clearTimeout(that._onTimer);
clearTimeout(that._offTimer);
that._callbacks = that._onTimer = that._offTimer = that.active = that._data = null
},
_createCallback: function(target, data, coords) {
var that = this;
return function() {
if (that.active === target) {
that._callbacks[EVENT_FOCUS_MOVE]({
data: that._data,
x: coords.x,
y: coords.y
});
onCheck(true)
}
else
that._callbacks[EVENT_FOCUS_ON]({
data: data,
x: coords.x,
y: coords.y
}, onCheck)
};
function onCheck(result) {
that.changing = null;
that.disabled = !result;
if (result) {
that._data = data;
that.active = target;
clearTimeout(that._offTimer);
that._offTimer = null
}
}
},
turnOn: function(target, data, coords, timeout) {
var that = this;
that.disabled = false;
that.x = coords.x;
that.y = coords.y;
clearTimeout(that._onTimer);
that.changing = true;
that._onTimer = setTimeout(that._createCallback(target, data, coords), timeout)
},
move: function(target, data, coords) {
this.x = coords.x;
this.y = coords.y;
this._createCallback(target, data, coords)()
},
turnOff: function(timeout) {
var that = this;
if (that.active)
that._offTimer = that._offTimer || setTimeout(function() {
that._offTimer = null;
that._callbacks[EVENT_FOCUS_OFF]({data: that._data});
that._data = that.active = null;
that.disabled = true
}, timeout);
else {
clearTimeout(that._onTimer);
that._onTimer = null;
that.disabled = true
}
},
cancel: function() {
var that = this;
if (that.active)
that._callbacks[EVENT_FOCUS_OFF]({data: that._data});
clearTimeout(that._onTimer);
clearTimeout(that._offTimer);
that._data = that.active = that._onTimer = that._offTimer = null;
that.disabled = true
}
});
DX.viz.map._tests.Tracker = Tracker;
DX.viz.map._tests._DEBUG_forceEventMode = function(mode) {
setupEvents(mode)
};
DX.viz.map._tests.Focus = Focus;
DX.viz.map._tests._DEBUG_stubFocusType = function(focusType) {
Focus = focusType
};
DX.viz.map._tests._DEBUG_restoreFocusType = function() {
Focus = DX.viz.map._tests.Focus
};
DX.viz.map.Map.prototype._factory.createTracker = function(parameters) {
return new Tracker(parameters)
};
function getDistance(x1, y1, x2, y2) {
return _sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
}
function isTouchEvent(event) {
var type = event.originalEvent.type,
pointerType = event.originalEvent.pointerType;
return /^touch/.test(type) || /^MSPointer/.test(type) && pointerType !== 4 || /^pointer/.test(type) && pointerType !== 'mouse'
}
function selectItem(flags, items) {
var i = 0,
ii = flags.length,
item;
for (; i < ii; ++i)
if (flags[i]) {
item = items[i];
break
}
return _addNamespace(item || items[i], _NAME)
}
function setupEvents() {
var flags = [navigator.pointerEnabled, navigator.msPointerEnabled, 'ontouchstart' in window];
if (arguments.length)
flags = [arguments[0] === 'pointer', arguments[0] === 'MSPointer', arguments[0] === 'touch'];
EVENTS = {
start: selectItem(flags, ['pointerdown', 'MSPointerDown', 'touchstart mousedown', 'mousedown']),
move: selectItem(flags, ['pointermove', 'MSPointerMove', 'touchmove mousemove', 'mousemove']),
end: selectItem(flags, ['pointerup', 'MSPointerUp', 'touchend mouseup', 'mouseup']),
over: selectItem(flags, ['pointerover', 'MSPointerOver', 'mouseover', 'mouseover']),
out: selectItem(flags, ['pointerout', 'MSPointerOut', 'mouseout', 'mouseout']),
wheel: selectItem([], ['mousewheel DOMMouseScroll'])
}
}
function getEventCoords(event) {
var originalEvent = event.originalEvent,
touch = originalEvent.touches && originalEvent.touches[0] || {};
return {
x: touch.pageX || originalEvent.pageX || event.pageX,
y: touch.pageY || originalEvent.pageY || event.pageY
}
}
function getPointerId(event) {
return event.originalEvent.pointerId
}
function getMultitouchEventCoords(event, pointerId) {
var originalEvent = event.originalEvent;
if (originalEvent.pointerId !== undefined)
originalEvent = originalEvent.pointerId === pointerId ? originalEvent : null;
else
originalEvent = originalEvent.touches[pointerId];
return originalEvent ? {
x: originalEvent.pageX || event.pageX,
y: originalEvent.pageY || event.pageY
} : null
}
})(DevExpress, jQuery);
/*! Module viz-vectormap, file themeManager.js */
(function(DX, $, undefined) {
var _Number = Number,
_extend = $.extend,
_each = $.each;
var ThemeManager = DX.viz.core.BaseThemeManager.inherit({
_themeSection: 'map',
_initializeTheme: function() {
var that = this;
that._initializeFont(that._theme.marker.font);
that._initializeFont(that._theme.tooltip.font);
that._initializeFont(that._theme.legend.font);
that._initializeFont(that._theme.loadingIndicator.font)
},
dispose: function() {
var that = this;
that.callBase.apply(that, arguments);
that._areasPalette = that._markersPalette = null;
return that
},
getBackgroundSettings: function(options) {
var theme = this._theme.background,
merged = _extend({}, theme, options);
return {
strokeWidth: merged.borderWidth,
stroke: merged.borderColor,
fill: merged.color
}
},
getCommonAreaSettings: function(options) {
var settings = _extend({}, this._theme.area, options);
this._areasPalette = new DX.viz.core.GradientPalette(settings.palette, settings.paletteSize);
this._DEBUG_areasPalette = this._areasPalette;
return settings
},
getAreaSettings: function(commonSettings, options) {
options = options || {};
var settings = _extend({}, commonSettings, options);
settings.borderWidth = _Number(settings.borderWidth) || 0;
settings.borderColor = settings.borderColor || null;
if (options.color === undefined && options.paletteIndex >= 0)
settings.color = this._areasPalette.getColor(options.paletteIndex);
settings.color = settings.color || null;
settings.hoveredBorderWidth = _Number(settings.hoveredBorderWidth) || settings.borderWidth;
settings.hoveredBorderColor = settings.hoveredBorderColor || settings.borderColor;
settings.hoveredColor = settings.hoveredColor || settings.color;
settings.selectedBorderWidth = _Number(settings.selectedBorderWidth) || settings.borderWidth;
settings.selectedBorderColor = settings.selectedBorderColor || settings.borderColor;
settings.selectedColor = settings.selectedColor || settings.color;
return settings
},
getCommonMarkerSettings: function(options) {
options = options || {};
var theme = this._theme.marker,
allSettings = {};
_each(theme, function(name) {
if (name[0] === '_') {
var partialTheme = theme[name] || {},
partialOptions = options[name] || {},
settings = _extend({}, theme, partialTheme, options, partialOptions);
settings.font = _extend({}, theme.font, partialTheme.font, options.font, partialOptions.font);
allSettings[name.substr(1)] = settings
}
});
this._markersPalette = new DX.viz.core.Palette(options.palette || theme.palette, {
stepHighlight: 50,
theme: this.themeName()
});
this._DEBUG_markersPalette = this._markersPalette;
return allSettings
},
getMarkerSettings: function(commonSettings, options, type) {
options = options || {};
var common = commonSettings[type],
settings = _extend({}, common, options);
settings.font = _extend({}, common.font, options.font);
settings.borderWidth = _Number(settings.borderWidth) || 0;
settings.borderColor = settings.borderColor || null;
settings.color = settings.color || null;
settings.opacity = settings.opacity || null;
settings.hoveredBorderWidth = _Number(settings.hoveredBorderWidth) || settings.borderWidth;
settings.hoveredBorderColor = settings.hoveredBorderColor || settings.borderColor;
settings.hoveredColor = settings.hoveredColor || settings.color;
settings.hoveredOpacity = settings.hoveredOpacity || settings.opacity;
settings.selectedBorderWidth = _Number(settings.selectedBorderWidth) || settings.borderWidth;
settings.selectedBorderColor = settings.selectedBorderColor || settings.borderColor;
settings.selectedColor = settings.selectedColor || settings.color;
settings.selectedOpacity = settings.selectedOpacity || settings.opacity;
return settings
},
getMarkerColors: function(count) {
var i = 0,
colors = [];
for (; i < count; ++i)
colors.push(this._markersPalette.getNextColor());
this._markersPalette.reset();
return colors
},
getControlBarSettings: function(options) {
var theme = this._theme.controlBar,
merged = _extend({}, theme, options);
return _extend({}, options, {shape: {
strokeWidth: merged.borderWidth,
stroke: merged.borderColor,
fill: merged.color
}})
},
getLoadIndicatorSettings: function(options) {
var theme = this._theme.loadingIndicator;
return _extend(true, {}, theme, options)
},
getTooltipSettings: function(options) {
var theme = this._theme.tooltip,
merged = _extend({}, theme, options),
borderOptions = _extend({}, theme.border, options && options.border, options && !options.border && {color: options.borderColor});
return _extend({}, options, {
color: merged.color,
border: borderOptions,
text: {
strokeWidth: 0,
stroke: 'none',
fill: 'none',
font: _extend({}, theme.font, merged.font),
'class': 'dxm-tooltip-text'
},
arrowLength: merged.arrowLength,
paddingLeftRight: merged.paddingLeftRight,
paddingTopBottom: merged.paddingTopBottom,
opacity: merged.opacity,
shadow: _extend({}, theme.shadow, merged.shadow)
})
},
getLegendSettings: function(options) {
return _extend(true, {}, this._theme.legend, options)
},
getLegendItemSettings: function(item) {
var color = item.color;
if (color === undefined && item.paletteIndex >= 0)
color = this._areasPalette.getColor(item.paletteIndex);
return {
text: item.text,
color: color
}
},
patchRtlSettings: function(rtlEnabledOption) {
var theme = this._theme;
if (rtlEnabledOption || theme.rtlEnabled && rtlEnabledOption !== false)
$.extend(true, theme, theme._rtl)
}
});
DX.viz.map._tests.ThemeManager = ThemeManager;
DX.viz.map.Map.prototype._factory.createThemeManager = function() {
return new ThemeManager
}
})(DevExpress, jQuery);
/*! Module viz-vectormap, file mapItemsManager.js */
(function(DX, $, undefined) {
var _String = String,
_isString = DX.utils.isString,
_isArray = DX.utils.isArray,
_isFunction = DX.utils.isFunction,
_extend = $.extend,
_each = $.each,
_map = $.map;
var SELECTION_MODE_NONE = 'none',
SELECTION_MODE_SINGLE = 'single',
SELECTION_MODE_MULTIPLE = 'multiple';
var MapItemsManager = DX.Class.inherit({
_rootClass: null,
ctor: function(parameters) {
var that = this;
that._container = parameters.container;
that._renderer = parameters.renderer;
that._projection = parameters.projection;
that._themeManager = parameters.themeManager;
that._tracker = parameters.tracker;
that._ready = parameters.ready;
that._root = that._renderer.createGroup({'class': that._rootClass});
that._items = [];
that._context = {
renderer: that._renderer,
root: that._root,
projection: that._projection,
selectItem: function(index, state, noCallback) {
that.selectItem(index, state, noCallback)
}
}
},
dispose: function() {
var that = this;
that._container = that._renderer = that._projection = that._themeManager = that._tracker = that._ready = that._root = that._source = that._context = null;
return that
},
clean: function() {
var that = this;
that._rendered = false;
that._root.detach();
that._customizeCallback = that._clickCallback = that._selectionChangedCallback = null;
that._destroyItems();
return that
},
render: function(options) {
options = options || {};
var that = this;
that._rendered = true;
that._customizeCallback = _isFunction(options.customize) ? options.customize : null;
that._clickCallback = _isFunction(options.click) ? options.click : null;
that._selectionChangedCallback = _isFunction(options.selectionChanged) ? options.selectionChanged : null;
that._hoverEnabled = 'hoverEnabled' in options ? !!options.hoverEnabled : true;
var selectionMode = _String(options.selectionMode).toLowerCase();
that._selectionMode = selectionMode === SELECTION_MODE_NONE || selectionMode === SELECTION_MODE_SINGLE || selectionMode === SELECTION_MODE_MULTIPLE ? selectionMode : SELECTION_MODE_SINGLE;
that._root.append(that._container);
if (that._source !== null)
that._createItems();
return that
},
_destroyItems: function() {
var that = this;
that._root.clear();
_each(that._items, function(_, item) {
item.clean().dispose()
});
that._items = [];
that._selectedItems = null
},
_getItemSettings: null,
_createItem: null,
_isItemSelected: null,
_arrangeItems: null,
_createItems: function() {
var that = this;
that._selectedItems = that._selectionMode === SELECTION_MODE_MULTIPLE ? {} : null;
var selectedList = [];
_each(_isArray(that._source) ? that._source : [], function(i, dataItem) {
dataItem = dataItem || {};
var settings = that._customizeCallback && that._customizeCallback.call(dataItem, dataItem) || {};
var source = {
item: dataItem,
coords: that._getItemCoordinates(dataItem),
attrs: that._getItemAttributes(dataItem)
};
settings = that._getItemSettings(source, settings);
var item = that._createItem(settings);
item.init(that._context, source, i).render(settings).locate();
that._items.push(item);
if (that._isItemSelected(source, settings))
selectedList.push(i)
});
if (that._selectionMode !== SELECTION_MODE_NONE && selectedList.length > 0) {
if (that._selectionMode === SELECTION_MODE_SINGLE)
selectedList = [selectedList[selectedList.length - 1]];
_each(selectedList, function(_, index) {
that.selectItem(index, true, true)
})
}
that._arrangeItems();
that._ready && that._ready()
},
_processSource: null,
setData: function(data) {
var that = this;
that._source = null;
if (_isString(data))
$.getJSON(data).done(updateSource).fail(function(_0, _1, error) {
updateSource(null)
});
else
updateSource(data);
return that;
function updateSource(source) {
that._source = that._processSource(source) || 0;
if (that._rendered) {
that._tracker.reset();
that._destroyItems();
that._createItems()
}
}
},
transform: function(transform) {
this._root.applySettings(transform);
return this
},
redraw: function() {
_each(this._items, function(_, item) {
item.locate()
});
return this
},
hoverItem: function(index, state) {
if (this._hoverEnabled)
this._items[index].setHovered(!!state);
return this
},
_raiseSelectionChanged: function(item) {
var that = this;
if (that._selectionChangedCallback)
setTimeout(function() {
that._selectionChangedCallback && that._selectionChangedCallback.call(item.proxy, item.proxy)
}, 0)
},
selectItem: function(index, state, noCallback) {
var that = this;
if (that._selectionMode === SELECTION_MODE_NONE)
return that;
var item = that._items[index],
previous = item.selected;
item.setSelected(!!state);
if (item.selected === previous)
return that;
if (!noCallback)
that._raiseSelectionChanged(item);
if (item.selected && that._selectionMode === SELECTION_MODE_SINGLE && that._selectedItems) {
that._selectedItems.setSelected(false);
if (!noCallback)
that._raiseSelectionChanged(that._selectedItems);
that._selectedItems = null
}
if (that._selectionMode === SELECTION_MODE_SINGLE)
that._selectedItems = item.selected ? item : null;
else if (item.selected)
that._selectedItems[index] = item;
else
delete that._selectedItems[index];
return that
},
clearSelection: function() {
var that = this;
if (that._selectionMode === SELECTION_MODE_NONE)
return that;
if (that._selectionMode === SELECTION_MODE_SINGLE) {
if (that._selectedItems) {
that._selectedItems.setSelected(false);
that._raiseSelectionChanged(that._selectedItems);
that._selectedItems = null
}
}
else
_each(that._selectedItems, function(i, item) {
item.setSelected(false);
that._raiseSelectionChanged(item);
delete that._selectedItems[i]
});
return that
},
raiseClick: function(index, $event) {
var that = this,
item = that._items[index];
if (that._clickCallback)
setTimeout(function() {
that._clickCallback && that._clickCallback.call(item.proxy, item.proxy, $event)
}, 0);
return that
},
getProxyItems: function() {
return _map(this._items, function(item) {
return item.proxy
})
},
getProxyItem: function(index) {
return this._items[index].proxy
}
});
DX.viz.map._internal.mapItemBehavior = {
init: function(ctx, src, index) {
var that = this;
that._ctx = ctx;
that._src = src;
that._coords = that._project(ctx.projection, src.coords);
that._data = {
index: index,
type: that._type
};
that.hovered = that.selected = false;
that.proxy = createProxy(that, src.attrs, ctx.selectItem);
that.proxy.type = that._type;
that._init();
return that
},
dispose: function() {
disposeItem(this.proxy);
disposeItem(this);
return this
},
locate: function() {
var that = this;
that._locate(that._transform(that._ctx.projection, that._coords));
return that
},
clean: function() {
this._root.detach();
return this
},
render: function(settings) {
var that = this;
that._root = that._createRoot().append(that._ctx.root);
that._render(settings);
return that
},
setHovered: function(state) {
var that = this;
that.hovered = !!state;
that._onHover();
if (!that.selected)
if (that.hovered)
that._setHoveredState();
else
that._setDefaultState();
return that
},
setSelected: function(state) {
var that = this;
that.selected = !!state;
if (that.selected)
that._setSelectedState();
else
that.setHovered(that.hovered);
return that
}
};
function createProxy(item, attributes, selectItem) {
attributes = attributes || {};
return {
attribute: function(name) {
return name !== undefined ? attributes[name] : _extend({}, attributes)
},
selected: function(state, _noEvent) {
if (state !== undefined) {
if (item.selected !== !!state)
selectItem(item._data.index, !!state, _noEvent);
return this
}
else
return item.selected
}
}
}
function disposeItem(item) {
_each(item, function(name) {
item[name] = null
})
}
DX.viz.map._tests.MapItemsManager = MapItemsManager;
DX.viz.map.Map.prototype._factory.MapItemsManager = MapItemsManager
})(DevExpress, jQuery);
/*! Module viz-vectormap, file areasManager.js */
(function(DX, $, undefined) {
var _DATA_KEY = DX.viz.map.__DATA_KEY;
var AreasManager = DX.viz.map.Map.prototype._factory.MapItemsManager.inherit({
_rootClass: 'dxm-areas',
_processSource: function(source) {
var isGeoJson = source && source.type === 'FeatureCollection';
this._getItemCoordinates = isGeoJson ? getCoordinatesGeoJson : getCoordinatesDefault;
this._getItemAttributes = isGeoJson ? getAttributesGeoJson : getAttributesDefault;
return isGeoJson ? source.features : source
},
clean: function() {
this._commonSettings = null;
return this.callBase.apply(this, arguments)
},
render: function(options) {
this._commonSettings = this._themeManager.getCommonAreaSettings(options || {});
return this.callBase.apply(this, arguments)
},
_getItemSettings: function(_, options) {
return this._themeManager.getAreaSettings(this._commonSettings, options)
},
_createItem: function() {
return new Area
},
_isItemSelected: function(source, settings) {
return source.attrs.isSelected || settings.isSelected
},
_arrangeItems: $.noop
});
function getCoordinatesDefault(dataItem) {
return dataItem.coordinates
}
function getCoordinatesGeoJson(dataItem) {
var coordinates;
if (dataItem.geometry) {
var type = dataItem.geometry.type;
coordinates = dataItem.geometry.coordinates;
if (coordinates && (type === 'Polygon' || type === 'MultiPolygon'))
type === 'MultiPolygon' && (coordinates = [].concat.apply([], coordinates));
else
coordinates = undefined
}
return coordinates
}
function getAttributesDefault(dataItem) {
return dataItem.attributes
}
function getAttributesGeoJson(dataItem) {
return dataItem.properties
}
function Area(){}
$.extend(Area.prototype, DX.viz.map._internal.mapItemBehavior, {
_type: 'area',
_project: function(projection, coords) {
return projection.projectArea(coords)
},
_init: $.noop,
_createRoot: function() {
return this._ctx.renderer.createSimplePath()
},
_render: function(settings) {
var that = this;
that._styles = {
normal: {
'class': 'dxm-area',
stroke: settings.borderColor,
strokeWidth: settings.borderWidth,
fill: settings.color
},
hovered: {
'class': 'dxm-area dxm-area-hovered',
stroke: settings.hoveredBorderColor,
strokeWidth: settings.hoveredBorderWidth,
fill: settings.hoveredColor
},
selected: {
'class': 'dxm-area dxm-area-selected',
stroke: settings.selectedBorderColor,
strokeWidth: settings.selectedBorderWidth,
fill: settings.selectedColor
}
};
that._root.applySettings(that._styles.normal).data(_DATA_KEY, that._data);
return that
},
_transform: function(projection, coords) {
return projection.getAreaCoordinates(coords)
},
_locate: function(coords) {
this._root.applySettings({d: coords})
},
_onHover: $.noop,
_setDefaultState: function() {
this._root.applySettings(this._styles.normal).toBackground()
},
_setHoveredState: function() {
this._root.applySettings(this._styles.hovered).toForeground()
},
_setSelectedState: function() {
this._root.applySettings(this._styles.selected).toForeground()
}
});
DX.viz.map._tests.AreasManager = AreasManager;
DX.viz.map._tests.Area = Area;
DX.viz.map.Map.prototype._factory.createAreasManager = function(parameters) {
return new AreasManager(parameters)
}
})(DevExpress, jQuery);
/*! Module viz-vectormap, file markersManager.js */
(function(DX, $, undefined) {
var _Number = Number,
_String = String,
_isFinite = isFinite,
_round = Math.round,
_max = Math.max,
_min = Math.min,
_extend = $.extend,
_isArray = DX.utils.isArray,
_processCircleSettings = DX.viz.renderers.processCircleSettings;
var CLASS_DEFAULT = 'dxm-marker',
CLASS_HOVERED = 'dxm-marker dxm-marker-hovered',
CLASS_SELECTED = 'dxm-marker dxm-marker-selected',
TRACKER_SETTINGS = {
stroke: 'none',
strokeWidth: 0,
fill: '#000000',
opacity: 0.0001
};
var _DATA_KEY = DX.viz.map.__DATA_KEY;
var DEFAULT_MARKER_TYPE = 'dot',
MARKER_TYPES = {};
var MarkersManager = DX.viz.map.Map.prototype._factory.MapItemsManager.inherit({
_rootClass: 'dxm-markers',
ctor: function() {
var that = this;
that.callBase.apply(that, arguments);
that._context.getColors = function(count) {
return that._themeManager.getMarkerColors(count)
};
that._filter = that._renderer.createFilter('shadow').applySettings({
x: '-40%',
y: '-40%',
width: '180%',
height: '200%',
color: '#000000',
opacity: 0.2,
dx: 0,
dy: 1,
blur: 1
}).append()
},
dispose: function() {
this._filter.dispose();
this._filter = null;
return this.callBase.apply(this, arguments)
},
_getItemCoordinates: function(dataItem) {
return dataItem.coordinates
},
_getItemAttributes: function(dataItem) {
return dataItem.attributes
},
_processSource: function(source) {
return source
},
clean: function() {
var that = this;
that._commonSettings = null;
return that.callBase.apply(that, arguments)
},
render: function(options) {
var that = this;
that._commonSettings = that._themeManager.getCommonMarkerSettings(options);
that._commonSettings._filter = that._filter.ref;
that._commonType = parseMarkerType(options && options.type);
return that.callBase.apply(that, arguments)
},
_arrangeBubbles: function() {
var markers = this._items,
bubbles = [],
i,
ii = markers.length,
marker,
values = [];
for (i = 0; i < ii; ++i) {
marker = markers[i];
if (marker.type === 'bubble') {
bubbles.push(marker);
if (marker.value !== null)
values.push(marker.value)
}
}
var minValue = _min.apply(null, values),
maxValue = _max.apply(null, values),
deltaValue = maxValue - minValue || 1;
for (i = 0, ii = bubbles.length; i < ii; ++i) {
marker = bubbles[i];
marker.setSize(marker.value !== null ? (marker.value - minValue) / deltaValue : 0)
}
},
_getItemSettings: function(source, options) {
var type = parseMarkerType(source.item.type, this._commonType),
style = _extend(source.item.style, options);
style = this._themeManager.getMarkerSettings(this._commonSettings, style, type);
_extend(source.item, {text: source.item.text || style.text});
style._type = type;
return style
},
_createItem: function(settings) {
return new MARKER_TYPES[settings._type]
},
_isItemSelected: function(source, settings) {
return source.item.isSelected || settings.isSelected
},
_arrangeItems: function() {
this._arrangeBubbles()
},
addMarker: function(dataItem) {
var that = this,
index = that._items.length,
marker = that._createItem(dataItem, index);
that._items.push(marker);
if (marker._selected)
that.selectItem(index, true, true);
that._arrangeItems();
return that
}
});
var baseMarkerBehavior = _extend({}, DX.viz.map._internal.mapItemBehavior, {
_type: 'marker',
_project: function(projection, coords) {
return projection.projectPoint(coords)
},
_init: function() {
this.proxy.coordinates = createCoordinatesGetter(this._src.coords);
this.proxy.text = this._src.item.text
},
_createRoot: function() {
return this._ctx.renderer.createGroup()
},
_render: function(settings) {
var that = this;
that._root.applySettings({'class': CLASS_DEFAULT});
that._create(settings, that._ctx.renderer, that._root);
that._createText(settings, that._ctx.renderer, that._root);
return that
},
_createText: function(settings, renderer, root) {
var that = this;
if (!that._src.item.text)
return;
var rootbox = that._root.getBBox(),
text = renderer.createText(that._src.item.text, 0, 0, {
align: 'center',
font: settings.font
}).append(root),
textBox = text.getBBox(),
x = _round(-textBox.x + rootbox.width / 2) + 2,
y = _round(-textBox.y - textBox.height / 2) - 1;
text.applySettings({
x: x,
y: y
});
renderer.createRect(x + textBox.x - 1, y + textBox.y - 1, textBox.width + 2, textBox.height + 2, 0, TRACKER_SETTINGS).data(_DATA_KEY, that._data).append(root)
},
_transform: function(projection, coords) {
return projection.getPointCoordinates(coords)
},
_locate: function(coords) {
this._root.applySettings({
translateX: coords.x,
translateY: coords.y
})
},
_onHover: function() {
this.hovered && this._root.toForeground()
},
_setDefaultState: function() {
this._root.applySettings({'class': CLASS_DEFAULT}).toBackground();
this._applyDefault()
},
_setHoveredState: function() {
this._root.applySettings({'class': CLASS_HOVERED});
this._applyHovered()
},
_setSelectedState: function() {
this._root.applySettings({'class': CLASS_SELECTED}).toForeground();
this._applySelected()
}
});
function createCoordinatesGetter(coordinates) {
return function() {
return [_Number(coordinates[0]), _Number(coordinates[1])]
}
}
function DotMarker(){}
_extend(DotMarker.prototype, baseMarkerBehavior, {
type: 'dot',
_create: function(style, renderer, root) {
var that = this,
size = style.size > 0 ? _Number(style.size) : 0,
hoveredSize = size,
selectedSize = size + (style.selectedStep > 0 ? _Number(style.selectedStep) : 0),
hoveredBackSize = hoveredSize + (style.backStep > 0 ? _Number(style.backStep) : 0),
selectedBackSize = selectedSize + (style.backStep > 0 ? _Number(style.backStep) : 0),
settings = _processCircleSettings(0, 0, size, style.borderWidth);
that._dotDefault = {
cx: settings.cx,
cy: settings.cy,
r: settings.r,
stroke: style.borderColor,
strokeWidth: style.borderWidth,
fill: style.color,
filter: style.shadow ? style._filter : null
};
that._dotHovered = {
cx: settings.cx,
cy: settings.cy,
r: hoveredSize / 2,
stroke: style.hoveredBorderColor,
strokeWidth: style.hoveredBorderWidth,
fill: style.hoveredColor
};
that._dotSelected = {
cx: settings.cx,
cy: settings.cy,
r: selectedSize / 2,
stroke: style.selectedBorderColor,
strokeWidth: style.selectedBorderWidth,
fill: style.selectedColor
};
that._backDefault = {
cx: settings.cx,
cy: settings.cy,
r: settings.r,
stroke: 'none',
strokeWidth: 0,
fill: style.backColor,
opacity: style.backOpacity
};
that._backHovered = {
cx: settings.cx,
cy: settings.cy,
r: hoveredBackSize / 2,
stroke: 'none',
strokeWidth: 0,
fill: style.backColor,
opacity: style.backOpacity
};
that._backSelected = {
cx: settings.cx,
cy: settings.cy,
r: selectedBackSize / 2,
stroke: 'none',
strokeWidth: 0,
fill: style.backColor,
opacity: style.backOpacity
};
that._back = renderer.createCircle().applySettings(that._backDefault).data(_DATA_KEY, that._data).append(root);
that._dot = renderer.createCircle().applySettings(that._dotDefault).data(_DATA_KEY, that._data).append(root)
},
_destroy: function() {
this._back = this._dot = null
},
_applyDefault: function() {
this._back.applySettings(this._backDefault);
this._dot.applySettings(this._dotDefault)
},
_applyHovered: function() {
this._back.applySettings(this._backHovered);
this._dot.applySettings(this._dotHovered)
},
_applySelected: function() {
this._back.applySettings(this._backSelected);
this._dot.applySettings(this._dotSelected)
}
});
function BubbleMarker(){}
_extend(BubbleMarker.prototype, baseMarkerBehavior, {
type: 'bubble',
_create: function(style, renderer, root) {
var that = this;
that._minSize = style.minSize > 0 ? _Number(style.minSize) : 0;
that._maxSize = style.maxSize > that._minSize ? _Number(style.maxSize) : that._minSize;
that.value = _isFinite(that._src.item.value) ? _Number(that._src.item.value) : null;
that._default = {
stroke: style.borderColor,
strokeWidth: style.borderWidth,
fill: style.color,
opacity: style.opacity
};
that._hovered = {
stroke: style.hoveredBorderColor,
strokeWidth: style.hoveredBorderWidth,
fill: style.hoveredColor,
opacity: style.hoveredOpacity
};
that._selected = {
stroke: style.selectedBorderColor,
strokeWidth: style.selectedBorderWidth,
fill: style.selectedColor,
opacity: style.selectedOpacity
};
that._bubble = renderer.createCircle(0, 0, style.maxSize / 2).applySettings(that._default).data(_DATA_KEY, that._data).append(root)
},
_destroy: function() {
this._bubble = null
},
_applyDefault: function() {
this._bubble.applySettings(this._default)
},
_applyHovered: function() {
this._bubble.applySettings(this._hovered)
},
_applySelected: function() {
this._bubble.applySettings(this._selected)
},
setSize: function(ratio) {
var that = this,
settings = _processCircleSettings(0, 0, that._minSize + ratio * (that._maxSize - that._minSize), that._default.strokeWidth);
that._default.cx = that._hovered.cx = that._selected.cx = settings.cx;
that._default.cy = that._hovered.cy = that._selected.cy = settings.cy;
that._default.r = that._hovered.r = that._selected.r = settings.r;
that._bubble.applySettings(settings);
return that
}
});
function PieMarker(){}
_extend(PieMarker.prototype, baseMarkerBehavior, {
type: 'pie',
_create: function(style, renderer, root) {
var that = this,
settings = _processCircleSettings(0, 0, style.size > 0 ? _Number(style.size) : 0, style.borderWidth);
that._pieDefault = {opacity: style.opacity};
that._pieHovered = {opacity: style.hoveredOpacity};
that._pieSelected = {opacity: style.selectedOpacity};
that._borderDefault = {
stroke: style.borderColor,
strokeWidth: style.borderWidth
};
that._borderHovered = {
stroke: style.hoveredBorderColor,
strokeWidth: style.hoveredBorderWidth
};
that._borderSelected = {
stroke: style.selectedBorderColor,
strokeWidth: style.selectedBorderWidth
};
var srcValues = that._src.item.values,
i = 0,
ii = _isArray(srcValues) ? srcValues.length : 0,
values = [],
value,
sum = 0;
for (; i < ii; ++i) {
value = _Number(srcValues[i]);
if (_isFinite(value)) {
values.push(value);
sum += value
}
}
that._pie = renderer.createGroup(that._pieDefault);
var translator = new DX.viz.core.Translator1D(0, sum, 90, 450),
startAngle = translator.translate(0),
endAngle,
colors = that._ctx.getColors(values.length);
for (value = 0, i = 0, ii = values.length; i < ii; ++i) {
value += values[i];
endAngle = translator.translate(value);
renderer.createArc(settings.cx, settings.cy, settings.r, 0, startAngle, endAngle, {fill: colors[i]}).data(_DATA_KEY, that._data).append(that._pie);
startAngle = endAngle
}
that._pie.append(root);
that._border = renderer.createCircle(settings.cx, settings.cy, settings.r, that._borderDefault).data(_DATA_KEY, that._data).append(root)
},
_destroy: function() {
this._pie = this._border = null
},
_applyDefault: function() {
this._pie.applySettings(this._pieDefault);
this._border.applySettings(this._borderDefault)
},
_applyHovered: function() {
this._pie.applySettings(this._pieHovered);
this._border.applySettings(this._borderHovered)
},
_applySelected: function() {
this._pie.applySettings(this._pieSelected);
this._border.applySettings(this._borderSelected)
}
});
function ImageMarker(){}
_extend(ImageMarker.prototype, baseMarkerBehavior, {
type: 'image',
_create: function(style, renderer, root) {
var that = this,
size = style.size > 0 ? _Number(style.size) : 0,
hoveredSize = size + (style.hoveredStep > 0 ? _Number(style.hoveredStep) : 0),
selectedSize = size + (style.selectedStep > 0 ? _Number(style.selectedStep) : 0);
that._default = {
x: -size / 2,
y: -size / 2,
width: size,
height: size
};
that._hovered = {
x: -hoveredSize / 2,
y: -hoveredSize / 2,
width: hoveredSize,
height: hoveredSize
};
that._selected = {
x: -selectedSize / 2,
y: -selectedSize / 2,
width: selectedSize,
height: selectedSize
};
that._image = renderer.createImage().applySettings(that._default).applySettings({
href: that._src.item.url,
location: 'center'
}).append(root);
that._tracker = renderer.createRect().applySettings(that._default).applySettings(TRACKER_SETTINGS).data(_DATA_KEY, that._data).append(root)
},
_destroy: function() {
this._image = this._tracker = null
},
_applyDefault: function() {
this._image.applySettings(this._default);
this._tracker.applySettings(this._default)
},
_applyHovered: function() {
this._image.applySettings(this._hovered);
this._tracker.applySettings(this._hovered)
},
_applySelected: function() {
this._image.applySettings(this._selected);
this._tracker.applySettings(this._selected)
}
});
MARKER_TYPES['dot'] = DotMarker;
MARKER_TYPES['bubble'] = BubbleMarker;
MARKER_TYPES['pie'] = PieMarker;
MARKER_TYPES['image'] = ImageMarker;
function parseMarkerType(type, defaultType) {
return MARKER_TYPES[type] && type || defaultType || DEFAULT_MARKER_TYPE
}
var __originalDefaultMarkerType = DEFAULT_MARKER_TYPE,
__originalMarkerTypes = $.extend({}, MARKER_TYPES);
DX.viz.map._tests.stubMarkerTypes = function(markerTypes, defaultMarkerType) {
DEFAULT_MARKER_TYPE = defaultMarkerType;
MARKER_TYPES = markerTypes
};
DX.viz.map._tests.restoreMarkerTypes = function() {
DEFAULT_MARKER_TYPE = __originalDefaultMarkerType;
MARKER_TYPES = __originalMarkerTypes
};
DX.viz.map._tests.baseMarkerBehavior = baseMarkerBehavior;
DX.viz.map._tests.MarkersManager = MarkersManager;
DX.viz.map._tests.DotMarker = DotMarker;
DX.viz.map._tests.BubbleMarker = BubbleMarker;
DX.viz.map._tests.PieMarker = PieMarker;
DX.viz.map._tests.ImageMarker = ImageMarker;
DX.viz.map.Map.prototype._factory.createMarkersManager = function(parameters) {
return new MarkersManager(parameters)
}
})(DevExpress, jQuery);
DevExpress.MOD_VIZ_VECTORMAP = true
}
if (!DevExpress.MOD_VIZ_SPARKLINES) {
if (!DevExpress.MOD_VIZ_CORE)
throw Error('Required module is not referenced: viz-core');
/*! Module viz-sparklines, file baseSparkline.js */
(function($, DX) {
var TOOLTIP_MARGIN = 100,
TOOLTIP_ARROW_MARGIN = 10,
DEFAULT_LINE_SPACING = 6,
DEFAULT_EVENTS_DELAY = 200,
TOUCH_EVENTS_DELAY = 1000,
_extend = $.extend,
_abs = Math.abs,
_Number = Number,
_round = Math.round,
core = DX.viz.core,
CoreFactory = core.CoreFactory;
function DEFAULT_CUSTOMIZE_TOOLTIP(customizeObject) {
return {text: customizeObject.valueText.join('
')}
}
DX.viz.sparklines = {};
DX.viz.sparklines.DEFAULT_CUSTOMIZE_TOOLTIP = DEFAULT_CUSTOMIZE_TOOLTIP;
DX.viz.sparklines.BaseSparkline = core.BaseWidget.inherit({
render: function() {
this._refresh();
return this
},
_rendererType: DX.viz.renderers.Renderer,
_clean: function() {
if (this._tooltipShown) {
this._tooltip.dispose();
this._tooltip = null;
this._tooltipShown = null;
this._tooltipGroup.clear()
}
this._tooltipContainer.detach();
this._cleanWidgetElements()
},
_optionChanged: function(optionName, value) {
if (optionName === 'size' && this._allOptions) {
this._clean();
this._canvas = this._calculateCanvas();
this._renderer.resize(this._canvas.width, this._canvas.height);
if (!this._isContainerVisible())
return;
this._allOptions.size = value;
this._redrawWidgetElements();
this._prepareTooltipContainer()
}
else if (optionName === 'dataSource' && this._allOptions)
this._refreshDataSource();
else
this.callBase.apply(this, arguments)
},
_init: function() {
this.callBase();
this._canvas = this._calculateCanvas();
this._renderer = new this._rendererType({
cssClass: this._widgetClass + ' ' + this._widgetClass + '-' + this._widgetType,
pathModified: this.option('pathModified'),
rtl: this.option('rtlEnabled')
});
this._renderer.recreateCanvas(this._canvas.width, this._canvas.height);
this._createHtmlElements();
this._createTooltipGroups();
this._initTooltipEvents();
this._drawContainer()
},
_dispose: function() {
var that = this;
that.callBase();
that._disposeWidgetElements();
that._disposeTooltipEvents();
that._renderer.dispose();
that._tooltipRenderer.dispose();
that._translatorX = null;
that._translatorY = null;
delete that._renderer;
delete that._tooltipRenderer;
delete that._tooltipTrackerGroup;
delete that._tooltipGroup;
delete that._tooltipContainer
},
_render: function() {
var that = this;
that._canvas = that._calculateCanvas();
that._renderer.resize(that._canvas.width, that._canvas.height);
if (!that._isContainerVisible()) {
that._incidentOccured('W2001', [that.NAME]);
return
}
that._prepareOptions();
that._createWidgetElements();
that._drawWidgetElements();
that._drawn()
},
_isContainerVisible: function() {
var that = this,
canvas = that._canvas,
enoughWidth = canvas.width - canvas.left - canvas.right > 0,
enoughHeight = canvas.height - canvas.top - canvas.bottom > 0;
return canvas.height && canvas.width && enoughHeight && enoughWidth
},
_createWidgetElements: function() {
this._createRange();
this._createTranslator()
},
_prepareOptions: function(defaultOptions) {
var that = this,
userOptions = that.option() || {},
options,
defaultTheme,
theme;
defaultTheme = core.findTheme('default');
defaultTheme = defaultTheme[this._widgetType];
options = _extend(true, {}, defaultOptions, userOptions);
if (typeof options.theme === 'string') {
theme = core.findTheme(options.theme);
theme = theme[this._widgetType]
}
else
theme = options.theme;
return _extend(true, {}, defaultTheme, theme, options)
},
_calculateCanvas: function() {
var that = this,
canvas = {},
sizeOptions = that.option('size') || {},
marginOptions = that.option('margin') || {},
defaultSize = that._defaultSize,
container = that._element(),
width = sizeOptions.width >= 0 ? _Number(sizeOptions.width) : container.width(),
height = sizeOptions.height >= 0 ? _Number(sizeOptions.height) : container.height();
if (!width && _Number(sizeOptions.width) !== 0)
width = defaultSize.width;
if (!height && _Number(sizeOptions.height) !== 0)
height = defaultSize.height;
return {
width: width,
height: height,
top: _Number(marginOptions.top) || defaultSize.top,
bottom: _Number(marginOptions.bottom) || defaultSize.bottom,
left: _Number(marginOptions.left) || defaultSize.left,
right: _Number(marginOptions.right) || defaultSize.right
}
},
_createTooltipGroups: function() {
var that = this,
renderer,
root,
widgetClass = that._widgetClass;
that._tooltipRenderer = renderer = new that._rendererType({
cssClass: widgetClass + ' ' + widgetClass + '-tooltip',
pathModified: this.option('pathModified'),
rtl: this.option('rtlEnabled')
});
renderer.recreateCanvas(1, 1);
that._tooltipContainer = $('
');
renderer.draw(that._tooltipContainer[0]);
root = renderer.getRoot();
that._tooltipGroup = renderer.createGroup({
'class': widgetClass + '-tooltip-group',
style: {'z-index': '1'}
}).append(root);
that._tooltipTrackerGroup = renderer.createGroup({'class': widgetClass + '-tooltip-tracker-group'}).append(root);
that._tooltipTracker = that._createTooltipTracker().append(that._tooltipTrackerGroup)
},
_createTooltipTracker: function() {
return this._tooltipRenderer.createRect(0, 0, 0, 0, 0, {
fill: 'grey',
opacity: 0
})
},
_initTooltipEvents: function() {
var that = this,
data = {
widget: that,
container: that._tooltipTracker
};
that._showTooltipCallback = function() {
that._showTooltipTimeout = null;
if (!that._tooltipShown) {
that._tooltipShown = true;
that._showTooltip()
}
that._DEBUG_showCallback && that._DEBUG_showCallback()
};
that._hideTooltipCallback = function() {
that._hideTooltipTimeout = null;
if (that._tooltipShown) {
that._tooltipShown = false;
that._hideTooltip()
}
that._DEBUG_hideCallback && that._DEBUG_hideCallback()
};
that._disposeCallbacks = function() {
that = that._showTooltipCallback = that._hideTooltipCallback = that._disposeCallbacks = null
};
that._tooltipTracker.on(mouseEvents, data).on(touchEvents, data);
that._tooltipTracker.on(menuEvents)
},
_disposeTooltipEvents: function() {
clearTimeout(this._showTooltipTimeout);
clearTimeout(this._hideTooltipTimeout);
this._showTooltipTimeout = this._showTooltipTimeout = null;
this._tooltipTracker.off();
this._disposeCallbacks()
},
_drawContainer: function() {
this._renderer.draw(this._element()[0])
},
_createTranslator: function() {
this._translatorX = CoreFactory.createTranslator2D(this._ranges.arg, this._canvas, {direction: "horizontal"});
this._translatorY = CoreFactory.createTranslator2D(this._ranges.val, this._canvas)
},
_prepareTooltipOptions: function() {
var that = this,
canvas = that._canvas,
tooltipOpt = that._allOptions.tooltip,
size = that._getTooltipSize(true),
defaultOptions = {
canvasWidth: size.width,
canvasHeight: size.height,
paddingLeftRight: tooltipOpt.paddingLeftRight,
paddingTopBottom: tooltipOpt.paddingTopBottom,
arrowLength: tooltipOpt.arrowLength,
cloudHorizontalPosition: tooltipOpt.horizontalAlignment,
cloudVerticalPosition: tooltipOpt.verticalAlignment,
lineSpacing: tooltipOpt.font.lineSpacing !== undefined && tooltipOpt.font.lineSpacing !== null ? tooltipOpt.font.lineSpacing : DEFAULT_LINE_SPACING
},
autoJustify = !$.isFunction(that._allOptions.tooltip.customizeText) && !$.isFunction(that._allOptions.tooltip.customizeTooltip),
options = $.extend(defaultOptions, that._allOptions.tooltip, {
customizeTooltip: autoJustify ? DEFAULT_CUSTOMIZE_TOOLTIP : that._allOptions.tooltip.customizeTooltip,
_justify: that._allOptions.tooltip._justify || autoJustify,
_rtl: that.option('rtlEnabled')
});
that._tooltipOptions = {
size: size,
options: options
};
return options
},
_prepareTooltipContainer: function() {
var that = this,
canvas = that._canvas,
width = canvas.width,
height = canvas.height,
renderer = that._tooltipRenderer;
that._updateTooltipSizeToNormal();
that._tooltipTracker.applySettings({
width: width,
height: height
});
that._tooltipContainer.appendTo(that._element());
that._tooltipInitializated = false;
that._canShowTooltip = that._allOptions.tooltip.enabled
},
_isTooltipVisible: function() {
return this._tooltip.enabled() && this._tooltip.prepare(this._getTooltipData(), {offset: 0})
},
_createTooltip: function() {
var that = this;
that._tooltip = CoreFactory.createTooltip(that._prepareTooltipOptions(), that._tooltipGroup, that._tooltipRenderer);
if (that._isTooltipVisible()) {
that._tooltip.show();
that._updateTooltipSizeToWide();
that._checkTooltipSize();
that._updateTooltipSizeToNormal()
}
else
that._canShowTooltip = false
},
_doShowTooltip: function(delay) {
var that = this;
if (!that._canShowTooltip)
return;
++that._DEBUG_clearHideTooltipTimeout;
clearTimeout(that._hideTooltipTimeout);
that._hideTooltipTimeout = null;
clearTimeout(that._showTooltipTimeout);
++that._DEBUG_showTooltipTimeoutSet;
that._showTooltipTimeout = setTimeout(that._showTooltipCallback, delay)
},
_doHideTooltip: function(delay) {
var that = this;
if (!that._canShowTooltip)
return;
++that._DEBUG_clearShowTooltipTimeout;
clearTimeout(that._showTooltipTimeout);
that._showTooltipTimeout = null;
clearTimeout(that._hideTooltipTimeout);
++that._DEBUG_hideTooltipTimeoutSet;
that._hideTooltipTimeout = setTimeout(that._hideTooltipCallback, delay)
},
_getNormalTooltipSize: function() {
var size = {};
size.width = this._canvas.width;
size.left = 0;
size.tooltipLeft = _round(size.width / 2);
return size
},
_getWideTooltipSize: function(leftWidthDelta, rightWidthDelta) {
var that = this,
canvas = that._canvas,
horizontalPos = that._allOptions.tooltip.horizontalAlignment,
widthDelta = leftWidthDelta + rightWidthDelta,
size = {};
size.width = canvas.width + widthDelta;
size.left = -leftWidthDelta;
if (horizontalPos === 'right')
size.tooltipLeft = _round(canvas.width / 2);
else if (horizontalPos === 'left')
size.tooltipLeft = _round(canvas.width / 2) + widthDelta;
else
size.tooltipLeft = _round(size.width / 2);
return size
},
_getTooltipSize: function(isNormal, leftWidthDelta, rightWidthDelta, heightDelta) {
var that = this,
canvas = that._canvas,
isVerticalPosTop = !(that._allOptions.tooltip.verticalAlignment === 'bottom'),
size = !isNormal && (leftWidthDelta || rightWidthDelta) ? that._getWideTooltipSize(leftWidthDelta, rightWidthDelta) : that._getNormalTooltipSize(),
yDelta = heightDelta > 0 ? heightDelta + TOOLTIP_MARGIN : TOOLTIP_MARGIN;
size.height = canvas.height + yDelta;
size.top = isVerticalPosTop ? -size.height : -canvas.height;
size.trackerY = isVerticalPosTop ? yDelta : 0;
size.tooltipY = isVerticalPosTop ? _round(canvas.height / 2) + yDelta - TOOLTIP_ARROW_MARGIN : _round(canvas.height / 2);
return size
},
_checkTooltipSize: function() {
var that = this,
tooltip = that._tooltip,
options = that._tooltipOptions.options,
tooltipBBox = tooltip.getBBox(),
getWide = that._allOptions.tooltip.allowContainerResizing,
leftDelta = -tooltipBBox.x,
rightDelta = tooltipBBox.x + tooltipBBox.width - that._canvas.width,
topDelta = tooltipBBox.height - TOOLTIP_MARGIN,
size;
if (leftDelta > 0 || rightDelta > 0 || topDelta > 0)
if (getWide) {
that._tooltipOptions.size = size = that._getTooltipSize(false, leftDelta > 0 ? leftDelta : 0, rightDelta > 0 ? rightDelta : 0, topDelta > 0 ? topDelta : 0);
tooltip.setSize(size.width, size.height);
that._updateTooltipSizeToWide()
}
else {
that._canShowTooltip = false;
tooltip.hide()
}
},
_updateTooltipSizeToWide: function() {
var that = this,
size = that._tooltipOptions.size,
renderer = that._tooltipRenderer;
renderer.resize(size.width, size.height);
renderer.getRoot().applySettings({style: {
left: size.left,
top: size.top,
position: 'absolute',
overflow: 'hidden'
}});
that._tooltipTracker.applySettings({
y: size.trackerY,
x: -size.left
});
that._tooltip.move(size.tooltipLeft, size.tooltipY)
},
_updateTooltipSizeToNormal: function() {
var that = this,
renderer = that._tooltipRenderer,
canvas = that._canvas;
renderer.resize(canvas.width, canvas.height);
renderer.getRoot().applySettings({style: {
left: 0,
top: -canvas.height,
position: 'absolute'
}});
that._tooltipTracker.applySettings({
y: 0,
x: 0
})
},
_showTooltip: function() {
if (!this._tooltipInitializated) {
this._createTooltip();
this._tooltipInitializated = true;
if (!this._canShowTooltip)
return
}
this._updateTooltipSizeToWide();
this._tooltip.show()
},
_hideTooltip: function() {
this._updateTooltipSizeToNormal();
this._tooltip.hide()
},
showLoadingIndicator: $.noop
});
var menuEvents = {
'contextmenu.sparkline-tooltip': function(event) {
if (DX.ui.events.isTouchEvent(event) || DX.ui.events.isPointerEvent(event))
event.preventDefault()
},
'MSHoldVisual.sparkline-tooltip': function(event) {
event.preventDefault()
}
};
var mouseEvents = {
'mouseover.sparkline-tooltip': function(event) {
isPointerDownCalled = false;
var widget = event.data.widget;
widget._x = event.pageX;
widget._y = event.pageY;
widget._tooltipTracker.off(mouseMoveEvents).on(mouseMoveEvents, event.data);
widget._doShowTooltip(DEFAULT_EVENTS_DELAY)
},
'mouseout.sparkline-tooltip': function(event) {
if (isPointerDownCalled)
return;
var widget = event.data.widget;
widget._tooltipTracker.off(mouseMoveEvents);
widget._doHideTooltip(DEFAULT_EVENTS_DELAY)
}
};
var mouseMoveEvents = {'mousemove.sparkline-tooltip': function(event) {
var widget = event.data.widget;
if (widget._showTooltipTimeout && (_abs(widget._x - event.pageX) > 3 || _abs(widget._y - event.pageY) > 3)) {
widget._x = event.pageX;
widget._y = event.pageY;
widget._doShowTooltip(DEFAULT_EVENTS_DELAY)
}
}};
var active_touch_tooltip_widget = null,
touchstartTooltipProcessing = function(event) {
event.preventDefault();
var widget = active_touch_tooltip_widget;
if (widget && widget !== event.data.widget)
widget._doHideTooltip(DEFAULT_EVENTS_DELAY);
widget = active_touch_tooltip_widget = event.data.widget;
widget._doShowTooltip(TOUCH_EVENTS_DELAY);
widget._touch = true
},
touchstartDocumentProcessing = function() {
var widget = active_touch_tooltip_widget;
if (widget) {
if (!widget._touch) {
widget._doHideTooltip(DEFAULT_EVENTS_DELAY);
active_touch_tooltip_widget = null
}
widget._touch = null
}
},
touchendDocumentProcessing = function() {
var widget = active_touch_tooltip_widget;
if (widget)
if (widget._showTooltipTimeout) {
widget._doHideTooltip(DEFAULT_EVENTS_DELAY);
active_touch_tooltip_widget = null
}
},
isPointerDownCalled = false;
var touchEvents = {
'pointerdown.sparkline-tooltip': function(event) {
touchstartTooltipProcessing(event)
},
'touchstart.sparkline-tooltip': function(event) {
touchstartTooltipProcessing(event)
}
};
$(document).on({
'pointerdown.sparkline-tooltip': function() {
isPointerDownCalled = true;
touchstartDocumentProcessing()
},
'touchstart.sparkline-tooltip': function() {
touchstartDocumentProcessing()
},
'pointerup.sparkline-tooltip': function() {
touchendDocumentProcessing()
},
'touchend.sparkline-tooltip': function() {
touchendDocumentProcessing()
}
});
DX.viz.sparklines.BaseSparkline._DEBUG_reset = function() {
active_touch_tooltip_widget = null
}
})(jQuery, DevExpress);
/*! Module viz-sparklines, file sparkline.js */
(function($, DX) {
var viz = DX.viz,
charts = viz.charts,
core = viz.core,
MIN_BAR_WIDTH = 1,
MAX_BAR_WIDTH = 50,
DEFAULT_BAR_INTERVAL = 4,
DEFAULT_CANVAS_WIDTH = 250,
DEFAULT_CANVAS_HEIGHT = 30,
DEFAULT_HORIZONTAL_MARGIN = 5,
DEFAULT_VERTICAL_MARGIN = 3,
DEFAULT_OPTIONS = {
disabled: false,
theme: 'default',
dataSource: [],
size: {},
margin: {},
type: 'line',
argumentField: 'arg',
valueField: 'val',
winlossThreshold: 0,
showFirstLast: true,
showMinMax: false,
redrawOnResize: false
},
ALLOWED_TYPES = {
line: true,
spline: true,
stepline: true,
area: true,
steparea: true,
splinearea: true,
bar: true,
winloss: true
},
_map = $.map,
_extend = $.extend,
_abs = Math.abs,
_round = Math.round,
_isFinite = isFinite,
_Number = Number,
_String = String;
viz.sparklines.Sparkline = viz.sparklines.BaseSparkline.inherit({
_widgetType: 'sparkline',
_widgetClass: 'dxsl',
_defaultSize: {
width: DEFAULT_CANVAS_WIDTH,
height: DEFAULT_CANVAS_HEIGHT,
left: DEFAULT_HORIZONTAL_MARGIN,
right: DEFAULT_HORIZONTAL_MARGIN,
top: DEFAULT_VERTICAL_MARGIN,
bottom: DEFAULT_VERTICAL_MARGIN
},
_init: function() {
this.callBase();
this._refreshDataSource()
},
_handleDataSourceChanged: function() {
if (this._initialized) {
this._clean();
this._createWidgetElements();
this._drawWidgetElements()
}
},
_dataSourceOptions: function() {
return {
paginate: false,
_preferSync: true
}
},
_redrawWidgetElements: function() {
this._createTranslator();
this._correctPoints();
this._series.draw({
x: this._translatorX,
y: this._translatorY
});
this._seriesGroup.append(this._renderer.getRoot())
},
_disposeWidgetElements: function() {
delete this._seriesGroup;
delete this._seriesLabelGroup
},
_cleanWidgetElements: function() {
this._seriesGroup.detach();
this._seriesLabelGroup.detach();
this._seriesGroup.clear();
this._seriesLabelGroup.clear()
},
_createWidgetElements: function() {
this._createSeries();
this.callBase()
},
_drawWidgetElements: function() {
if (this._dataSource && this._dataSource.isLoaded())
this._drawSeries()
},
_prepareOptions: function() {
this._allOptions = this.callBase(DEFAULT_OPTIONS);
this._allOptions.type = _String(this._allOptions.type).toLowerCase();
if (!ALLOWED_TYPES[this._allOptions.type])
this._allOptions.type = 'line'
},
_createHtmlElements: function() {
this._seriesGroup = this._renderer.createGroup({'class': 'dxsl-series'});
this._seriesLabelGroup = this._renderer.createGroup({'class': 'dxsl-series-labels'})
},
_createSeries: function() {
var that = this,
renderer = that._renderer,
dataValidator;
that._prepareDataSource();
that._prepareSeriesOptions();
that._series = core.CoreFactory.createSeries(renderer, that._seriesOptions);
dataValidator = charts.factory.createDataValidator(that._simpleDataSource, [[that._series]], that._incidentOccured, {
checkTypeForAllData: false,
convertToAxisDataType: true,
sortingMethod: true
});
that._simpleDataSource = dataValidator.validate();
that._series._options.customizePoint = that._getCustomizeFunction();
that._series.updateData(that._simpleDataSource)
},
_parseNumericDataSource: function(data, argField, valField) {
var ignoreEmptyPoints = this.option('ignoreEmptyPoints');
return _map(data, function(dataItem, index) {
var item = null,
isDataNumber,
value;
if (dataItem !== undefined) {
item = {};
isDataNumber = _isFinite(dataItem);
item[argField] = isDataNumber ? _String(index) : dataItem[argField];
value = isDataNumber ? dataItem : dataItem[valField];
item[valField] = value === null ? ignoreEmptyPoints ? undefined : value : _Number(value);
item = item[argField] !== undefined && item[valField] !== undefined ? item : null
}
return item
})
},
_parseWinlossDataSource: function(data, argField, valField) {
var lowBarValue = -1,
zeroBarValue = 0,
highBarValue = 1,
delta = 0.0001,
target = this._allOptions.winlossThreshold;
return _map(data, function(dataItem) {
var item = {};
item[argField] = dataItem[argField];
if (_abs(dataItem[valField] - target) < delta)
item[valField] = zeroBarValue;
else if (dataItem[valField] > target)
item[valField] = highBarValue;
else
item[valField] = lowBarValue;
return item
})
},
_prepareDataSource: function() {
var that = this,
options = that._allOptions,
argField = options.argumentField,
valField = options.valueField,
dataSource = that._dataSource ? that._dataSource.items() : [],
data = that._parseNumericDataSource(dataSource, argField, valField);
if (options.type === 'winloss') {
that._winlossDataSource = data;
that._simpleDataSource = that._parseWinlossDataSource(data, argField, valField)
}
else
that._simpleDataSource = data
},
_prepareSeriesOptions: function() {
var that = this,
options = that._allOptions,
defaultPointOptions = {
border: {},
hoverStyle: {border: {}},
selectionStyle: {border: {}}
},
customPointOptions = {
size: options.pointSize,
symbol: options.pointSymbol,
border: {
visible: true,
width: 2
},
color: options.pointColor
};
that._seriesOptions = {
visible: true,
argumentField: options.argumentField,
valueField: options.valueField,
color: options.lineColor,
width: options.lineWidth,
widgetType: "chart"
};
that._seriesOptions.border = {
color: that._seriesOptions.color,
width: that._seriesOptions.width,
visible: true
};
that._seriesOptions.type = options.type === 'winloss' ? 'bar' : options.type;
if (options.type === 'winloss' || options.type === 'bar') {
that._seriesOptions.argumentAxisType = 'discrete';
that._seriesOptions.border.visible = false
}
if (~~options.type.indexOf('area') !== -1)
that._seriesOptions.opacity = that._allOptions.areaOpacity;
that._seriesOptions.seriesGroup = that._seriesGroup;
that._seriesOptions.seriesLabelsGroup = that._seriesLabelGroup;
that._seriesOptions.point = _extend(defaultPointOptions, customPointOptions);
that._seriesOptions.point.visible = false
},
_createBarCustomizeFunction: function(pointIndexes) {
var that = this,
options = that._allOptions,
winlossData = that._winlossDataSource;
return function() {
var index = this.index,
isWinloss = options.type === 'winloss',
target = isWinloss ? options.winlossThreshold : 0,
value = isWinloss ? winlossData[index][options.valueField] : this.value,
positiveColor = isWinloss ? options.winColor : options.barPositiveColor,
negativeColor = isWinloss ? options.lossColor : options.barNegativeColor,
color;
if (value >= target)
color = positiveColor;
else
color = negativeColor;
if (index === pointIndexes.first || index === pointIndexes.last)
color = options.firstLastColor;
if (index === pointIndexes.min)
color = options.minColor;
if (index === pointIndexes.max)
color = options.maxColor;
return {color: color}
}
},
_createLineCustomizeFunction: function(pointIndexes) {
var that = this,
options = that._allOptions;
return function() {
var color,
index = this.index;
if (index === pointIndexes.first || index === pointIndexes.last)
color = options.firstLastColor;
if (index === pointIndexes.min)
color = options.minColor;
if (index === pointIndexes.max)
color = options.maxColor;
return color ? {
visible: true,
border: {color: color}
} : {}
}
},
_getCustomizeFunction: function() {
var that = this,
options = that._allOptions,
dataSource = that._winlossDataSource || that._simpleDataSource,
drawnPointIndexes = that._getExtremumPointsIndexes(dataSource),
customizeFunction;
if (options.type === 'winloss' || options.type === 'bar')
customizeFunction = that._createBarCustomizeFunction(drawnPointIndexes);
else
customizeFunction = that._createLineCustomizeFunction(drawnPointIndexes);
return customizeFunction
},
_getExtremumPointsIndexes: function(data) {
var that = this,
options = that._allOptions,
lastIndex = data.length - 1,
indexes = {};
that._minMaxIndexes = that._findMinMax(data);
if (options.showFirstLast) {
indexes.first = 0;
indexes.last = lastIndex
}
if (options.showMinMax) {
indexes.min = that._minMaxIndexes.minIndex;
indexes.max = that._minMaxIndexes.maxIndex
}
return indexes
},
_findMinMax: function(data) {
var that = this,
valField = that._allOptions.valueField,
firstItem = data[0] || {},
firstValue = firstItem[valField] || 0,
min = firstValue,
max = firstValue,
minIndex = 0,
maxIndex = 0,
dataLength = data.length,
value,
i;
for (i = 1; i < dataLength; i++) {
value = data[i][valField];
if (value < min) {
min = value;
minIndex = i
}
if (value > max) {
max = value;
maxIndex = i
}
}
return {
minIndex: minIndex,
maxIndex: maxIndex
}
},
_createRange: function() {
var that = this,
series = that._series,
isBarType = series.type === 'bar',
DEFAULT_VALUE_RANGE_MARGIN = 0.15,
DEFAULT_ARGUMENT_RANGE_MARGIN = isBarType ? 0.1 : 0,
rangeData = series.getRangeData();
that._ranges = {
arg: new core.Range({
stick: !isBarType && series.getPoints().length > 1,
minValueMargin: DEFAULT_ARGUMENT_RANGE_MARGIN,
maxValueMargin: DEFAULT_ARGUMENT_RANGE_MARGIN
}),
val: new core.Range({
isValueRange: true,
keepValueMargins: true,
minValueMargin: DEFAULT_VALUE_RANGE_MARGIN,
maxValueMargin: DEFAULT_VALUE_RANGE_MARGIN
})
};
that._ranges.arg.addRange(rangeData.arg);
that._ranges.val.addRange(rangeData.val);
that._ranges.arg.applyValueMargins();
that._ranges.val.applyValueMargins()
},
_getBarWidth: function(pointsCount) {
var that = this,
canvas = that._canvas,
intervalWidth = pointsCount * DEFAULT_BAR_INTERVAL,
rangeWidth = canvas.width - canvas.left - canvas.right - intervalWidth,
width = _round(rangeWidth / pointsCount);
if (width < MIN_BAR_WIDTH)
width = MIN_BAR_WIDTH;
if (width > MAX_BAR_WIDTH)
width = MAX_BAR_WIDTH;
return width
},
_correctPoints: function() {
var that = this,
seriesType = that._allOptions.type,
seriesPoints = that._series.getPoints(),
pointsLength = seriesPoints.length,
barWidth,
i;
if (seriesType === 'bar' || seriesType === 'winloss') {
barWidth = that._getBarWidth(pointsLength);
for (i = 0; i < pointsLength; i++)
seriesPoints[i].correctCoordinates({
width: barWidth,
offset: 0
})
}
},
_drawSeries: function() {
var that = this;
if (that._simpleDataSource.length !== 0) {
that._correctPoints();
that._series.draw({
x: that._translatorX,
y: that._translatorY
});
that._seriesGroup.append(that._renderer.getRoot());
that._prepareTooltipContainer()
}
},
_isTooltipVisible: function() {
return this.callBase() && this._dataSource.length !== 0
},
_getTooltipData: function() {
var that = this,
options = that._allOptions,
dataSource = that._winlossDataSource || that._simpleDataSource,
tooltip = that._tooltip;
if (dataSource.length === 0)
return {};
var minMax = that._minMaxIndexes,
valueField = options.valueField,
first = dataSource[0][valueField],
last = dataSource[dataSource.length - 1][valueField],
min = dataSource[minMax.minIndex][valueField],
max = dataSource[minMax.maxIndex][valueField],
formattedFirst = tooltip.formatValue(first),
formattedLast = tooltip.formatValue(last),
formattedMin = tooltip.formatValue(min),
formattedMax = tooltip.formatValue(max),
customizeObject = {
firstValue: formattedFirst,
lastValue: formattedLast,
minValue: formattedMin,
maxValue: formattedMax,
originalFirstValue: first,
originalLastValue: last,
originalMinValue: min,
originalMaxValue: max,
valueText: ['Start:', formattedFirst, 'End:', formattedLast, 'Min:', formattedMin, 'Max:', formattedMax]
};
if (options.type === 'winloss') {
customizeObject.originalThresholdValue = options.winlossThreshold;
customizeObject.thresholdValue = tooltip.formatValue(options.winlossThreshold)
}
return customizeObject
}
}).include(DX.ui.DataHelperMixin)
})(jQuery, DevExpress);
/*! Module viz-sparklines, file bullet.js */
(function($, DX) {
var charts = DX.viz.charts,
TARGET_MIN_Y = 0.02,
TARGET_MAX_Y = 0.98,
BAR_VALUE_MIN_Y = 0.1,
BAR_VALUE_MAX_Y = 0.9,
DEFAULT_CANVAS_WIDTH = 300,
DEFAULT_CANVAS_HEIGHT = 30,
DEFAULT_HORIZONTAL_MARGIN = 1,
DEFAULT_VERTICAL_MARGIN = 2,
DEFAULT_OPTIONS = {
disabled: false,
theme: 'default',
size: {},
margin: {}
},
_String = String,
_Number = Number,
_round = Math.round,
_isFinite = isFinite;
DX.viz.sparklines.Bullet = DX.viz.sparklines.BaseSparkline.inherit({
_widgetType: 'bullet',
_widgetClass: 'dxb',
_defaultSize: {
width: DEFAULT_CANVAS_WIDTH,
height: DEFAULT_CANVAS_HEIGHT,
left: DEFAULT_HORIZONTAL_MARGIN,
right: DEFAULT_HORIZONTAL_MARGIN,
top: DEFAULT_VERTICAL_MARGIN,
bottom: DEFAULT_VERTICAL_MARGIN
},
_disposeWidgetElements: function() {
delete this._zeroLevelPath;
delete this._targetPath;
delete this._barValuePath
},
_redrawWidgetElements: function() {
this._createTranslator();
this._drawBarValue();
this._drawTarget();
this._drawZeroLevel()
},
_cleanWidgetElements: function() {
this._zeroLevelPath.detach();
this._targetPath.detach();
this._barValuePath.detach()
},
_drawWidgetElements: function() {
this._drawBullet()
},
_createHtmlElements: function() {
var renderer = this._renderer;
this._zeroLevelPath = renderer.createPath(undefined, {'class': 'dxb-zero-level'});
this._targetPath = renderer.createPath(undefined, {'class': 'dxb-target'});
this._barValuePath = renderer.createPath(undefined, {'class': 'dxb-bar-value'})
},
_prepareOptions: function() {
var that = this,
options,
startScaleValue,
endScaleValue,
level,
value,
target;
that._allOptions = options = that.callBase(DEFAULT_OPTIONS);
if (that._allOptions.value === undefined)
that._allOptions.value = 0;
if (that._allOptions.target === undefined)
that._allOptions.target = 0;
options.value = value = _Number(options.value);
options.target = target = _Number(options.target);
if (that._allOptions.startScaleValue === undefined) {
that._allOptions.startScaleValue = target < value ? target : value;
that._allOptions.startScaleValue = that._allOptions.startScaleValue < 0 ? that._allOptions.startScaleValue : 0
}
if (that._allOptions.endScaleValue === undefined)
that._allOptions.endScaleValue = target > value ? target : value;
options.startScaleValue = startScaleValue = _Number(options.startScaleValue);
options.endScaleValue = endScaleValue = _Number(options.endScaleValue);
if (endScaleValue < startScaleValue) {
level = endScaleValue;
that._allOptions.endScaleValue = startScaleValue;
that._allOptions.startScaleValue = level;
that._allOptions.inverted = true
}
},
_createRange: function() {
var that = this,
options = that._allOptions;
that._ranges = {
arg: {
invert: options.inverted,
min: options.startScaleValue,
max: options.endScaleValue,
axisType: "continuous",
dataType: "numeric"
},
val: {
min: 0,
max: 1,
axisType: "continuous",
dataType: "numeric"
}
}
},
_drawBullet: function() {
var that = this,
options = that._allOptions,
isValidBounds = options.startScaleValue !== options.endScaleValue,
isValidMin = _isFinite(options.startScaleValue),
isValidMax = _isFinite(options.endScaleValue),
isValidValue = _isFinite(options.value),
isValidTarget = _isFinite(options.target);
if (isValidBounds && isValidMax && isValidMin && isValidTarget && isValidValue) {
this._drawBarValue();
this._drawTarget();
this._drawZeroLevel();
this._prepareTooltipContainer()
}
},
_getTargetParams: function() {
var that = this,
options = that._allOptions,
translatorX = that._translatorX,
translatorY = that._translatorY,
minY = translatorY.translate(TARGET_MIN_Y),
maxY = translatorY.translate(TARGET_MAX_Y),
x = translatorX.translate(options.target),
points = [{
x: x,
y: minY
}, {
x: x,
y: maxY
}];
return {
points: points,
stroke: options.targetColor,
strokeWidth: options.targetWidth
}
},
_getBarValueParams: function() {
var that = this,
options = that._allOptions,
translatorX = that._translatorX,
translatorY = that._translatorY,
startLevel = options.startScaleValue,
endLevel = options.endScaleValue,
value = options.value,
y2 = translatorY.translate(BAR_VALUE_MIN_Y),
y1 = translatorY.translate(BAR_VALUE_MAX_Y),
x1,
x2;
if (value > 0) {
x1 = startLevel <= 0 ? 0 : startLevel;
x2 = value >= endLevel ? endLevel : value
}
else {
x1 = endLevel >= 0 ? 0 : endLevel;
x2 = value >= startLevel ? value : startLevel
}
x1 = translatorX.translate(x1);
x2 = translatorX.translate(x2);
return {
points: [{
x: x1,
y: y1
}, {
x: x2,
y: y1
}, {
x: x2,
y: y2
}, {
x: x1,
y: y2
}],
fill: options.color
}
},
_getZeroLevelParams: function() {
var that = this,
options = that._allOptions,
translatorX = that._translatorX,
translatorY = that._translatorY,
minY = translatorY.translate(TARGET_MIN_Y),
maxY = translatorY.translate(TARGET_MAX_Y),
x = translatorX.translate(0);
return {
points: [{
x: x,
y: minY
}, {
x: x,
y: maxY
}],
stroke: options.targetColor,
strokeWidth: 1
}
},
_drawZeroLevel: function() {
var that = this,
options = that._allOptions,
params;
if (0 > options.endScaleValue || 0 < options.startScaleValue || !options.showZeroLevel)
return;
params = that._getZeroLevelParams();
that._zeroLevelPath.applySettings(params);
that._zeroLevelPath.append(that._renderer.getRoot())
},
_drawTarget: function() {
var that = this,
options = that._allOptions,
target = options.target,
startLevel = options.startScaleValue,
endLevel = options.endScaleValue,
params;
if (target > endLevel || target < startLevel || !options.showTarget)
return;
params = that._getTargetParams();
that._targetPath.applySettings(params);
that._targetPath.append(that._renderer.getRoot())
},
_drawBarValue: function() {
var that = this,
params = that._getBarValueParams();
that._barValuePath.applySettings(params);
that._barValuePath.append(that._renderer.getRoot())
},
_getTooltipData: function() {
var that = this,
tooltip = that._tooltip,
options = that._allOptions,
value = options.value,
target = options.target;
return {
originalValue: value,
originalTarget: target,
value: tooltip.formatValue(value),
target: tooltip.formatValue(target),
valueText: ['Actual Value:', value, 'Target Value:', target]
}
},
_getNormalTooltipSize: function() {
var size = {},
bbox = this._barValuePath.getBBox();
size.width = this._canvas.width;
size.left = 0;
size.tooltipLeft = bbox.x + _round(bbox.width / 2);
return size
},
_getWideTooltipSize: function(leftWidthDelta, rightWidthDelta) {
var that = this,
bbox = that._barValuePath.getBBox(),
horizontalPos = that._allOptions.tooltip.horizontalAlignment,
size = {};
size.width = leftWidthDelta + rightWidthDelta + that._canvas.width;
size.left = -leftWidthDelta;
if (horizontalPos === 'right')
size.tooltipLeft = bbox.x + _round(bbox.width / 2);
else if (horizontalPos === 'left')
size.tooltipLeft = _round(bbox.width / 2) + leftWidthDelta + rightWidthDelta + bbox.x;
else
size.tooltipLeft = _round(bbox.width / 2) + bbox.x + leftWidthDelta;
return size
}
})
})(jQuery, DevExpress);
/*! Module viz-sparklines, file dxSparkline.js */
(function($, DX, undefined) {
var ui = DX.ui,
viz = DX.viz;
DX.registerComponent("dxSparkline", viz.sparklines.Sparkline)
})(jQuery, DevExpress);
/*! Module viz-sparklines, file dxBullet.js */
(function($, DX, undefined) {
var ui = DX.ui,
viz = DX.viz;
DX.registerComponent("dxBullet", viz.sparklines.Bullet)
})(jQuery, DevExpress);
DevExpress.MOD_VIZ_SPARKLINES = true
}