!(function () { var scale = 1, transformY = 0, selected = true, globalScaleRatio = parseFloat(BI.Cache.getItem('scaleRatio')) || null; var html = document.getElementsByTagName('html')[0]; var wrapper = document.getElementById("wrapper"); var scrollContainer = document.createElement("div"); var fixedWrapper = document.createElement("div"); var fixedContainer = document.createElement('div'); // tooltip等fixed元素 scrollContainer.style.width = "100%"; scrollContainer.style.height = "100%"; fixedContainer.style.position = "absolute"; fixedContainer.style.top = "0"; fixedContainer.style.left = "0"; fixedContainer.style.width = "100%"; fixedContainer.style.height = "100%"; document.body.appendChild(scrollContainer); scrollContainer.appendChild(fixedWrapper); fixedWrapper.appendChild(wrapper); wrapper.appendChild(fixedContainer); var jQuery = $ || window.jQuery; var injectOffset = jQuery.fn.offset; var injectEventFix = jQuery.event.fix; var injectMouseInBounds = jQuery.fn.__isMouseInBounds__; var injectToolTipShow = null; var injectBubblesShow = null; var adjustHeight = BI.Combo.prototype.adjustHeight; var originalRender = BI.Widget._renderEngine; var injectSearchSearchStop = BI.Searcher.prototype._stopSearch; var injectTooltipsShow = BI.TooltipsController.prototype.show; var injectSwitcherPopup = BI.Switcher.prototype.populate; var injectSwitcherAdjustView = BI.Switcher.prototype.adjustView; var injectCreate = BI.createWidget; var callback = function () {}; BI.Searcher.prototype._search = function (result, searchResult, keyword) { var self = this, o = this.options, keyword = o.allowSearchBlank ? this.editor.getValue() : this._getLastSearchKeyword(); if (keyword === "" || this._stop) { return; } if (o.isAutoSearch) { var items = (o.adapter && ((o.adapter.getItems && o.adapter.getItems()) || o.adapter.attr("items"))) || []; var finding = BI.Func.getSearchResult(items, keyword); var match = finding.match, find = finding.find; this.popupView.populate(find, match, keyword); o.isAutoSync && o.adapter && o.adapter.getValue && this.popupView.setValue(o.adapter.getValue()); self.fireEvent(BI.Searcher.EVENT_SEARCHING); callback && callback.call(self, true); return; } this.popupView.loading && this.popupView.loading(); o.onSearch({ times: 1, keyword: keyword, selectedValues: o.adapter && o.adapter.getValue() }, function (searchResult, matchResult) { if (!self._stop) { var args = [].slice.call(arguments); if (args.length > 0) { args.push(keyword); } BI.Maskers.show(self.getName()); self.popupView.populate.apply(self.popupView, args); o.isAutoSync && o.adapter && o.adapter.getValue && self.popupView.setValue(o.adapter.getValue()); self.popupView.loaded && self.popupView.loaded(); self.fireEvent(BI.Searcher.EVENT_SEARCHING); callback && callback.call(self); } }); }; // 修正事件偏移 function correctEvent(e) { if (e && !e.corrected) { e.pageX = e.pageX / scale; e.pageY = (e.pageY - transformY) / scale; e.clientX = e.clientX / scale; e.clientY = (e.clientY - transformY) / scale; e.corrected = true; } return e; } function checkInPopupView(el) { var t = el.parentElement; var flag = false; do { if (t.className && t.className.indexOf("bi-popup-view") !== -1) { flag = true; break; } t = t.parentElement } while (t); return flag; } // 进行缩放 function transformScale(ratio) { var bounds = getScaleBounds(ratio); scale = bounds.scale; wrapper.style.width = bounds.width + "px"; wrapper.style.height = bounds.height + "px"; wrapper.style.transform = "scale(" + bounds.scale+ ")"; wrapper.style.transformOrigin = "top left"; wrapper.style["-ms-transform"] = "scale(" + bounds.scale+ ")"; wrapper.style["-ms-transform-origin"] = "top left"; wrapper.style.overflow = "hidden"; html.style.backgroundColor = "#ffffff"; scrollContainer.style.overflowX = globalScaleRatio === null ? "hidden" : "auto"; scrollContainer.style.overflowY = "auto"; fixedWrapper.style.overflow = "hidden"; fixedWrapper.style.width = bounds.width * scale + "px"; fixedWrapper.style.height = bounds.height * scale + "px"; window.scale = Math.max(window.devicePixelRatio * scale, 1); } // 取消缩放 function removeScale() { wrapper.style.width = "100%"; wrapper.style.height = "100%"; wrapper.style.transform = ""; wrapper.style.transformOrigin = ""; wrapper.style["-ms-transform"] = ""; wrapper.style["-ms-transform-origin"] = ""; wrapper.style.overflow = "hidden"; wrapper.style.top = ""; html.style.backgroundColor = "#ffffff"; scrollContainer.style.overflow = "hidden"; fixedWrapper.style.overflow = "hidden"; fixedWrapper.style.width = "100%"; fixedWrapper.style.height = "100%"; scale = 1; window.scale = window.devicePixelRatio; } // 获取缩放倍数,原模板宽高 function getScaleBounds(ratio) { var widgets = BI.designConfigure.widgets, layoutRatio = BI.designConfigure.layoutRatio, freeLayoutRatio = BI.designConfigure.freeLayoutRatio, freeWidgets = BI.designConfigure.freeWidgetIds; if (Object.keys(widgets).length === 0) { return { scale: 1, width: html.clientWidth, height: html.clientHeight } } var left = null, right = null, top = null, bottom = null, freeLeft = null, freeRight = null, freeTop = null, freeBottom = null; BI.each(widgets, function (wId, widget) { var bounds = widget.bounds || {}; if (BI.contains(freeWidgets, wId)) { freeLeft = BI.isNull(freeLeft) ? bounds.left : Math.min(freeLeft, bounds.left); freeRight = Math.max(freeRight, bounds.left + bounds.width); freeTop = BI.isNull(freeTop) ? bounds.top : Math.min(freeTop, bounds.top); freeBottom = Math.max(freeBottom, bounds.top + bounds.height); } else { left = BI.isNull(left) ? bounds.left : Math.min(left, bounds.left); right = Math.max(right, bounds.left + bounds.width); top = BI.isNull(top) ? bounds.top : Math.min(top, bounds.top); bottom = Math.max(bottom, bounds.top + bounds.height); } }); var templateWidth = (Math.round((right / (layoutRatio.x || 1)) || (freeRight / (freeLayoutRatio.x || 1)))) + 60; var templateHeight = (Math.round((bottom / (layoutRatio.y || 1)) || (freeBottom / (freeLayoutRatio.y || 1)))) + 30; var scaleRatio = parseFloat((html.clientWidth / templateWidth).toFixed(1)); var resultWidth = 0; var resultHeight = 0; var bHeight = 0; if (ratio) { scaleRatio = ratio; bHeight = html.clientHeight / scaleRatio; resultWidth = templateWidth; resultHeight = Math.max(bHeight, templateHeight); } else { bHeight = html.clientHeight / scaleRatio; resultWidth = html.clientWidth / scaleRatio; resultHeight = Math.max(bHeight, scaleRatio === 1 ? html.clientHeight : templateHeight); } return { scale: scaleRatio, width: resultWidth, height: resultHeight }; } // 准备环境,主要是纠正事件偏移 function prepareEnv() { // IE的fixed元素不受transform:scale影响 injectToolTipShow = injectToolTipShow || BI.Tooltips.show; injectBubblesShow = injectBubblesShow || BI.Bubbles.show; jQuery.fn.__isMouseInBounds__ = function (e) { var offset2Body = this.get(0).getBoundingClientRect ? this.get(0).getBoundingClientRect() : this.offset(); var width = offset2Body.width || this.outerWidth(); var height = offset2Body.height || this.outerHeight(); var pageX = e.clientX * scale, pageY = e.clientY * scale + transformY; return !(pageX < Math.floor(offset2Body.left) || pageX > offset2Body.left + width || pageY < Math.floor(offset2Body.top) || pageY > offset2Body.top + height); }; jQuery.fn.offset = function( options ) { function getWindow( elem ) { return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 ? elem.defaultView || elem.parentWindow : false; } if ( arguments.length ) { return options === undefined ? this : this.each(function( i ) { jQuery.offset.setOffset( this, options, i ); }); } var docElem, win, box = { top: 0, left: 0 }, elem = this[ 0 ], doc = elem && elem.ownerDocument; if ( !doc ) { return; } docElem = doc.documentElement; // Make sure it's not a disconnected DOM node if ( !jQuery.contains( docElem, elem ) ) { return box; } var el = elem, offsetLeft = 0, offsetTop = 0; do{ offsetLeft += ( BI.isIE() ? window.getComputedStyle(el).position === "fixed" ? el.offsetLeft / scale : el.offsetLeft : el.offsetLeft ); offsetTop += ( BI.isIE() ? window.getComputedStyle(el).position === "fixed" ? el.offsetTop / scale : el.offsetTop : el.offsetTop ); el = el.offsetParent; } while( el ); var elm = elem; if (!checkInPopupView(elm)) { do{ if (elm === document.body) { break; } offsetLeft -= elm.scrollLeft || 0; offsetTop -= elm.scrollTop || 0; elm = elm.offsetParent; } while( elm ); } win = getWindow( doc ); return { top: offsetTop + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ), left: offsetLeft + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 ) }; }; jQuery.event.fix = function ( e ) { return correctEvent(injectEventFix.call(this, e)); }; // Popovers BI.Popovers = new BI.PopoverController({render: fixedContainer}); if (BI.isIE()) { BI.Combo.prototype.adjustHeight = function (e) { adjustHeight.call(this, e); var transformX = scrollContainer.scrollLeft; var transformY = scrollContainer.scrollTop; if (this.popupView) { if (!checkInPopupView(this.popupView.element[0])) { this.popupView.element[0].style.left = parseInt(this.popupView.element[0].style.left) * scale - transformX + "px"; this.popupView.element[0].style.top = parseInt(this.popupView.element[0].style.top) * scale - transformY + "px"; } else { var cBounds = BI.extend({}, this.popupView.element[0].getBoundingClientRect()); var pBounds = BI.extend({}, this.popupView.element[0].parentElement.getBoundingClientRect()); var hasScale = this.popupView.element[0].style.transform && this.popupView.element[0].style.transform.includes("scale"); var minWidth = parseInt(this.popupView.element[0].style.minWidth); var minHeight = parseInt(this.popupView.element[0].style.minHeight); cBounds.width = Math.max(cBounds.width, minWidth * scale); cBounds.height = Math.max(cBounds.height, minHeight * scale); if ((cBounds.left * scale + cBounds.width * (hasScale ? 1 : scale)) - transformX > body.clientWidth) { this.popupView.element[0].style.top = parseInt(pBounds.bottom) + "px"; this.popupView.element[0].style.left = parseInt(this.popupView.element[0].style.left) * scale - transformX + "px"; } else if (this.options.direction === "right") { this.popupView.element[0].style.top = parseInt(pBounds.top) + "px"; this.popupView.element[0].style.left = parseInt(pBounds.right) + "px"; } else if (parseInt(cBounds.top) >= parseInt(pBounds.top) && parseInt(cBounds.left) >= parseInt(pBounds.left)) { this.popupView.element[0].style.top = parseInt(pBounds.bottom) + "px"; this.popupView.element[0].style.left = parseInt(pBounds.left) + "px"; }else if (parseInt(cBounds.top) >= parseInt(pBounds.top) && parseInt(cBounds.left) < parseInt(pBounds.left)) { this.popupView.element[0].style.top = parseInt(pBounds.bottom) + "px"; this.popupView.element[0].style.left = parseInt(Math.min(pBounds.left, body.clientWidth - cBounds.width)) - transformX + "px"; } else { this.popupView.element[0].style.top = parseInt(pBounds.bottom) + "px"; this.popupView.element[0].style.left = parseInt(cBounds.left) * scale + "px"; } } this.popupView.element[0].style.transform = "scale(" + scale+ ")"; this.popupView.element[0].style.transformOrigin = "top left"; } }; BI.Bubbles.show = function (name, text, context, opt) { injectBubblesShow.call(this, name, text, context, opt); var tooltip = this.get(name); var transformX = scrollContainer.scrollLeft / scale, transformY = scrollContainer.scrollTop / scale; tooltip.element[0].style.left = parseInt(tooltip.element[0].style.left) * scale - transformX + "px"; tooltip.element[0].style.top = parseInt(tooltip.element[0].style.top) * scale - transformY + "px"; tooltip.element[0].style.transform = "scale(" + scale+ ")"; tooltip.element[0].style.transformOrigin = "top left"; } var tempAdd = BI.Popovers.add; BI.Popovers.add = function (name, popover, options, context) { tempAdd.call(this, name, popover, options, context); if (this.floatContainer[name].options.cls && this.floatContainer[name].options.cls.includes("bi-popup-view")) { this.floatContainer[name].element[0].style.setProperty("position", "absolute", "important"); } } // Searcher callback = function (flag) { var self = this; BI.defer(function () { if (self.popupView && self.popupView.element[0].parentElement) { var skip = BI.isNotEmptyString(self.popupView.element[0].parentElement.style.transformOrigin) && flag; if (!skip) { self.popupView.element[0].parentElement.style.left = parseInt(self.popupView.element[0].parentElement.style.left) * scale + "px"; self.popupView.element[0].parentElement.style.top = parseInt(self.popupView.element[0].parentElement.style.top) * scale + "px"; self.popupView.element[0].parentElement.style.transform = "scale(" + scale + ")"; self.popupView.element[0].parentElement.style.transformOrigin = "left top"; } } }) } BI.Searcher.prototype._stopSearch = function () { injectSearchSearchStop.apply(this, arguments); if (this.popupView && this.popupView.element[0].parentElement) { this.popupView.element[0].parentElement.style.transform = ""; this.popupView.element[0].parentElement.style.transformOrigin = ""; } } // switcher BI.Switcher.prototype.populate = function (items) { injectSwitcherPopup.apply(this, arguments); var self = this; BI.defer(function () { if (self.popupView) { self.popupView.element[0].parentElement.style.left = parseInt(self.popupView.element[0].parentElement.style.left) * scale + "px"; self.popupView.element[0].parentElement.style.top = parseInt(self.popupView.element[0].parentElement.style.top) * scale + "px"; self.popupView.element[0].parentElement.style.transform = "scale(" + scale + ")"; self.popupView.element[0].parentElement.style.transformOrigin = "left top"; } }) } BI.Switcher.prototype.adjustView = function () { injectSwitcherAdjustView.apply(this, arguments); if (this.popupView) { this.popupView.element[0].parentElement.style.left = parseInt(this.popupView.element[0].parentElement.style.left) * scale + "px"; this.popupView.element[0].parentElement.style.top = parseInt(this.popupView.element[0].parentElement.style.top) * scale + "px"; this.popupView.element[0].parentElement.style.transform = "scale(" + scale + ")"; this.popupView.element[0].parentElement.style.transformOrigin = "left top"; } } } BI.createWidget = function () { if (arguments[0] && arguments[0].element === "body") { arguments[0].element = fixedContainer; } return injectCreate.apply(this, arguments); }; BI.Widget.registerRenderEngine({ createElement: function (widget) { if (widget === "body") { return BI.$(wrapper); } return originalRender.createElement(widget); }, createFragment: function () { return originalRender.createFragment(); } }); BI.TooltipsController.prototype.show = function (e, name, text, level, context, opt) { opt || (opt = {}); var self = this; BI.each(this.showingTips, function (i, tip) { self.hide(i); }); this.showingTips = {}; if (!this.has(name)) { this.create(name, text, level, opt.container || "body"); } if (!opt.belowMouse) { var offset = context.element.offset(); var bounds = context.element.bounds(); if (bounds.height === 0 || bounds.width === 0) { return; } var top = offset.top + bounds.height + 5; } var tooltip = this.get(name); tooltip.setText(text); tooltip.element.css({ left: "0px", top: "0px" }); tooltip.visible(); tooltip.element.height(tooltip.element[0].scrollHeight); this.showingTips[name] = true; // scale影响要计算在内 // var scale = context.element.offset().left / context.element.get(0).getBoundingClientRect().left; // var x = (e.pageX || e.clientX) * scale + 15, y = (e.pageY || e.clientY) * scale + 15; var x = (e.pageX || e.clientX) + 15, y = (e.pageY || e.clientY) + 15; var originY = 0; if (BI.isIE()) { x = x * scale; y = y * scale; } else { x = x + scrollContainer.scrollLeft / scale; } if (x + tooltip.element.outerWidth() > BI.Widget._renderEngine.createElement("body").outerWidth()) { x -= tooltip.element.outerWidth() + 15; } var bodyHeight = BI.Widget._renderEngine.createElement("body").outerHeight(); if (y + tooltip.element.outerHeight() > bodyHeight || top + tooltip.element.outerHeight() > bodyHeight) { y -= tooltip.element.outerHeight() + 15; originY = y; !opt.belowMouse && (y = Math.min(y, offset.top - tooltip.element.outerHeight() - 5)); } else { originY = y; !opt.belowMouse && (y = Math.max(y, top)); } tooltip.element.css({ left: x < 0 ? 0 : x + "px", top: y < 0 ? 0 : y + "px" }); tooltip.element.hover(function () { self.remove(name); context.element.trigger("mouseleave.title" + context.getName()); }); if (BI.isIE()) { tooltip.element[0].style.transform = "scale(" + scale+ ")"; tooltip.element[0].style.transformOrigin = "top left"; } return this; } window.addEventListener('resize', updateScale); window.matchMedia && window.matchMedia('screen and (min-resolution: 2dppx)'). addListener(selectHandler); } function restoreEnv() { jQuery.fn.__isMouseInBounds__ = injectMouseInBounds; jQuery.fn.offset = injectOffset; jQuery.event.fix = injectEventFix; if (BI.isIE()) { BI.Combo.prototype.adjustHeight = adjustHeight; BI.Tooltips.show = injectToolTipShow; BI.Bubbles.show = injectBubblesShow; } BI.createWidget = injectCreate; // Popovers BI.Popovers = new BI.PopoverController(); BI.Widget.registerRenderEngine(originalRender); callback = function () {} BI.Switcher.prototype.populate = injectSwitcherPopup; BI.Switcher.prototype.adjustView = injectSwitcherAdjustView; BI.TooltipsController.prototype.show = injectTooltipsShow; document.body.onmousedown = null; window.removeEventListener('resize', updateScale); window.matchMedia && window.matchMedia('screen and (min-resolution: 2dppx)'). removeListener(selectHandler); } var selectHandler = BI.debounce(function () { selected && prepareEnv(); selected ? transformScale(globalScaleRatio) : removeScale(); !selected && restoreEnv(); }, 30); function updateScale () { if (html.getBoundingClientRect().width !== wrapper.getBoundingClientRect().width) { selectHandler(); } } var injectCaptureMouseMoves = BI.MouseMoveTracker.prototype.captureMouseMoves; var injectOnMouseMove = BI.MouseMoveTracker.prototype._onMouseMove; // 用jQEvent代替MouseEvent function injectMouseMoveTracker() { BI.MouseMoveTracker.prototype.captureMouseMoves = function (e) { var jQEvent = e.originalEvent ? e : jQuery.event.fix(e); injectCaptureMouseMoves.call(this, correctEvent(jQEvent)); }; BI.MouseMoveTracker.prototype._onMouseMove = function (e) { var jQEvent = e.originalEvent ? e : jQuery.event.fix(e); injectOnMouseMove.call(this, correctEvent(jQEvent)); } } injectMouseMoveTracker(); selectHandler(); BI.config("bi.constant.dashboard.toolbar.left.items", function (config) { return BI.concat(config, [{ type: "bi.multi_select_item", text: BI.i18nText("BI-Plugin-Scale_Adaptive"), selected: true, listeners: [{ eventName: BI.MultiSelectItem.EVENT_CHANGE, action: function () { selected = this.isSelected(); selectHandler(); } }] }, { type: 'bi.text_value_combo', text: '自定义缩放比例', width: 120, value: globalScaleRatio, items: [ { text: '自动', value: null, lgap: 10, }, { text: '50%', value: 0.5, lgap: 10, }, { text: '60%', value: 0.6, lgap: 10, }, { text: '70%', value: 0.7, lgap: 10, }, { lgap: 10, text: '80%', value: 0.8, lgap: 10, }, { lgap: 10, text: '90%', value: 0.9, lgap: 10, }, { lgap: 10, text: '100%', value: 1.0, lgap: 10, }, { lgap: 10, text: '110%', value: 1.1, lgap: 10, }, { lgap: 10, text: '120%', value: 1.2, lgap: 10, }, { lgap: 10, text: '130%', value: 1.3, lgap: 10, }, { lgap: 10, text: '140%', value: 1.4, lgap: 10, }, { lgap: 10, text: '150%', value: 1.5, lgap: 10, }, { lgap: 10, text: '160%', value: 1.6, lgap: 10, }, { lgap: 10, text: '170%', value: 1.7, lgap: 10, }, { lgap: 10, text: '180%', value: 1.8, lgap: 10, }, { lgap: 10, text: '190%', value: 1.9, lgap: 10, }, { lgap: 10, text: '200%', value: 2.0, lgap: 10, }, ], listeners: [{ eventName: "EVENT_CHANGE", action: function (v) { BI.Cache.setItem('scaleRatio', v); globalScaleRatio = v; selectHandler(); } }], }]) }); }());