| /** |
| * Simple draggable tool, just for demo or testing. |
| * Use jquery. |
| */ |
| (function (global) { |
| |
| var BORDER_WIDTH = 4; |
| var $ = global.jQuery; |
| |
| global.draggable = { |
| |
| /** |
| * @param {HTMLElement} mainEl |
| * @param {module:echarts/echarts~EChart} chart |
| * @param {Object} [opt] {width: ..., height: ...} |
| * @param {number} [opt.width] If not specified, use mainEl current width. |
| * @param {number} [opt.height] If not specified, use mainEl current height. |
| * @param {boolean} [opt.lockX=false] |
| * @param {boolean} [opt.lockY=false] |
| * @param {number} [opt.throttle=false] |
| * @return {type} description |
| */ |
| init: function (mainEl, chart, opt) { |
| opt = opt || {}; |
| |
| var chartResize = chart ? $.proxy(chart.resize, chart) : function () {}; |
| if (opt.throttle) { |
| chartResize = throttle(chartResize, opt.throttle, true, false); |
| } |
| |
| var mainEl = $(mainEl); |
| |
| $('.draggable-control').remove(); |
| |
| var controlEl = $( |
| '<div class="draggable-control">DRAG<span class="draggable-label"></span></div>' |
| ); |
| |
| controlEl.css({ |
| 'position': 'absolute', |
| 'border-radius': '30px', |
| 'width': '60px', |
| 'height': '60px', |
| 'line-height': '60px', |
| 'text-align': 'center', |
| 'background': '#333', |
| 'color': '#fff', |
| 'cursor': 'pointer', |
| 'font-size': '18px', |
| 'box-shadow': '0 0 5px #333', |
| '-webkit-user-select': 'none', |
| 'user-select': 'none' |
| }); |
| |
| var label = controlEl.find('.draggable-label'); |
| |
| label.css({ |
| 'display': 'block', |
| 'position': 'absolute', |
| 'color': '#000', |
| 'font-size': '12px', |
| 'text-align': 'center', |
| 'left': 0, |
| 'top': '65px', |
| 'width': '60px', |
| 'line-height': 1 |
| }); |
| |
| mainEl.css({ |
| 'position': 'absolute', |
| 'left': mainEl[0].offsetLeft + 'px', |
| 'top': mainEl[0].offsetTop + 'px', |
| 'width': mainEl[0].offsetWidth + 'px', |
| 'height': mainEl[0].offsetHeight + 'px', |
| 'border-style': 'solid', |
| 'border-color': '#ddd', |
| 'border-width': BORDER_WIDTH + 'px', |
| 'padding': 0, |
| 'margin': 0 |
| }); |
| |
| mainEl.parent().append(controlEl); |
| |
| var controlSize = controlEl[0].offsetWidth; |
| |
| var boxSizing = mainEl.css('box-sizing'); |
| |
| var borderBoxBroder = boxSizing === 'border-box' ? 2 * BORDER_WIDTH : 0; |
| var mainContentWidth = opt.width || (mainEl.width() + borderBoxBroder); |
| var mainContentHeight = opt.height || (mainEl.height() + borderBoxBroder); |
| |
| var mainOffset = mainEl.offset(); |
| resize( |
| mainOffset.left + mainContentWidth + BORDER_WIDTH, |
| mainOffset.top + mainContentHeight + BORDER_WIDTH, |
| true |
| ); |
| |
| var dragging = false; |
| |
| controlEl.on('mousedown', function () { |
| dragging = true; |
| }); |
| |
| $(document).on('mousemove', function (e) { |
| if (dragging) { |
| resize(e.pageX, e.pageY); |
| } |
| }); |
| |
| $(document).on('mouseup', function () { |
| dragging = false; |
| }); |
| |
| |
| |
| function resize(x, y, isInit) { |
| var mainOffset = mainEl.offset(); |
| var mainPosition = mainEl.position(); |
| var mainContentWidth = x - mainOffset.left - BORDER_WIDTH; |
| var mainContentHeight = y - mainOffset.top - BORDER_WIDTH; |
| |
| if (isInit || !opt.lockX) { |
| controlEl.css( |
| 'left', |
| (mainPosition.left + mainContentWidth + BORDER_WIDTH - controlSize / 2) + 'px' |
| ); |
| mainEl.css( |
| 'width', |
| (mainContentWidth + borderBoxBroder) + 'px' |
| ); |
| } |
| |
| if (isInit || !opt.lockY) { |
| controlEl.css( |
| 'top', |
| (mainPosition.top + mainContentHeight + BORDER_WIDTH - controlSize / 2) + 'px' |
| ); |
| mainEl.css( |
| 'height', |
| (mainContentHeight + borderBoxBroder) + 'px' |
| ); |
| } |
| |
| label.text(Math.round(mainContentWidth) + ' x ' + Math.round(mainContentHeight)); |
| |
| chartResize(); |
| } |
| } |
| }; |
| |
| function throttle(fn, delay, trailing, debounce) { |
| |
| var currCall = (new Date()).getTime(); |
| var lastCall = 0; |
| var lastExec = 0; |
| var timer = null; |
| var diff; |
| var scope; |
| var args; |
| var isSingle = typeof fn === 'function'; |
| delay = delay || 0; |
| |
| if (isSingle) { |
| return createCallback(); |
| } |
| else { |
| var ret = []; |
| for (var i = 0; i < fn.length; i++) { |
| ret[i] = createCallback(i); |
| } |
| return ret; |
| } |
| |
| function createCallback(index) { |
| |
| function exec() { |
| lastExec = (new Date()).getTime(); |
| timer = null; |
| (isSingle ? fn : fn[index]).apply(scope, args || []); |
| } |
| |
| var cb = function () { |
| currCall = (new Date()).getTime(); |
| scope = this; |
| args = arguments; |
| diff = currCall - (debounce ? lastCall : lastExec) - delay; |
| |
| clearTimeout(timer); |
| |
| if (debounce) { |
| if (trailing) { |
| timer = setTimeout(exec, delay); |
| } |
| else if (diff >= 0) { |
| exec(); |
| } |
| } |
| else { |
| if (diff >= 0) { |
| exec(); |
| } |
| else if (trailing) { |
| timer = setTimeout(exec, -diff); |
| } |
| } |
| |
| lastCall = currCall; |
| }; |
| |
| /** |
| * Clear throttle. |
| * @public |
| */ |
| cb.clear = function () { |
| if (timer) { |
| clearTimeout(timer); |
| timer = null; |
| } |
| }; |
| |
| return cb; |
| } |
| } |
| |
| })(window); |