const DEFAULT = 2; const ONDEMAND = 4; const AUTO = 8; const FAST = 16; const PASSIVE = 32; /** * * DataObject DO * @param cname * @param serverJsonObj * @constructor */ const DataObject = function (cname, serverJsonObj) { this.ctlName = cname; this.jsonObj = serverJsonObj; this.getVal = function (key) { return this.sonObj[key]; }; this.serVal = function (key, val) { this.jsonObj[key] = val; }; }; /** * * DataObjectList * @param name * @constructor */ const DataObjectList = function (name) { this.ctlName = name; this.list = null; this.isSorted = false; this.preSort = []; this.comparisonBasis = null; /** * * sorting * @param comparator (a,b) =====> a - b */ this.sortBy = function (comparator) { this.isSorted = true; this.comparisonBasis = comparator; this.preSort = []; for (let i = 0; i < this.list.length; i++) { this.preSort.push(this.list[i]); } this.quickSort(this.preSort, 0, this.preSort.length - 1, this.comparisonBasis, this); }; this.clearData = function () { this.isSorted = false; this.preSort = null; this.list = null; }; this.len = function () { if (this.list == null) return 0; return this.list.length; }; this.mergeJsonData = function (data, extdata) { this.list = []; for (let i = 0; i < data.length; i++) this.addObject(data[i]); if (this.comparisonBasis != null) this.sortBy(this.comparisonBasis); }; this.addObject = function (jsonObj) { this.list.push(new DataObject(this.ctlName, jsonObj)); }; this.assignJsonData = function (data) { this.clearData(); this.mergeJsonData(data); }; this.getRaw = function (index) { if (this.list == null) return null; return this.list[index]; }; this.getSorted = function (index) { if (this.list == null) return null; if (!this.isSorted) return this.getRaw(index); return this.preSort[index]; }; this.quickSort = function (a, left, right, comp, obj) { var inputVar = a; if (left > right) { // 一定要有这个判断,因为有递归left和i-1,若没有这个判断条件,该函数会进入无限死错位递归 return; } let i = left; let j = right; const pivot = inputVar[left]; // 基准总是取序列开头的元素 while (i !== j) { while ((comp(inputVar[j], pivot) > 0) && i < j) { j--; } while ((comp(inputVar[j], pivot) <= 0) && i < j) { i++; } if (i < j) { // 如果i==j跳出外层while const t = inputVar[i]; inputVar[i] = inputVar[j]; inputVar[j] = t; } } inputVar[left] = inputVar[i];// 交换基准数和k位置上的数 inputVar[i] = pivot; obj.quickSort(inputVar, left, i - 1, comp, obj); obj.quickSort(inputVar, i + 1, right, comp, obj); }; }; /** * * DOService * @param controlName * @constructor */ const DataObjectService = function (controlName, syncType, extparm) { this.ctlName = controlName; // 2=default 4=on-demand, 8=auto, 16:fast, 32=passive this.syncType = syncType; this.extParm = extparm; this.isDefault = ((syncType & DEFAULT) !== 0); this.isOnDemand = ((syncType & ONDEMAND) !== 0); this.isAuto = ((syncType & AUTO) !== 0); this.isFast = ((syncType & FAST) !== 0); this.isPassive = ((syncType & PASSIVE) !== 0); this.failedCount = 0; this.list = new DataObjectList(controlName); this.autoUpdateTimer = 0; this.autoInterval = 1000; this.callerThis = this; this.setUpInterval = function () { // URL + exparm if (this.autoUpdateTimer !== 0) clearInterval(this.autoUpdateTimer); this.autoUpdateTimer = setInterval(this.selfUpdateTick, this.autoInterval, this); setTimeout(this.selfUpdateTick, 1000, this); }; this.init = function () { this.appUrl = `${controlName}/list${extparm}`; if (!this.isFast || this.isOnDemand) { this.autoInterval = 300; } if (this.isFast) { this.appUrl = `${controlName}/get${extparm}`; } if (this.isAuto) { // timer this.setUpInterval(); } }; this.stopTimers = function () { clearInterval(this.autoUpdateTimer); this.autoUpdateTimer = 0; }; /** * * Automatica Update Tick, where obj is a replacement for "this" where "this" might be incorrect * @param obj : DataObjectService */ this.selfUpdateTick = function (obj) { get_data(obj.appUrl, obj.onDataReceived, obj); }; this.onDemandUpdate = function (obj) { get_data(obj.appUrl, obj.onDataReceived, obj); }; this.onDataReceived = function (data, sta) { const obj = this.callerThis; if (obj === undefined) { console.error('Cannot get callerThis in onDataReceived, please check'); console.error(this); } const output = first_parse(this, data); if (output.list === undefined || output.list.length === 0) { obj.failedCount++; if (obj.failedCount > 100) { obj.failedCount = 0; obj.stopTimers(); console.log('[排行榜返回为空git clone https://github.com/pentaho/mondrian-tck.git次数过多],暂停刷新'); } if (obj.failedCount === 2) { send_alert(`排行榜多次返回没有数据,请尝试重新加载! [${obj.appUrl}]`); } } else { obj.list.assignJsonData(output.list); } }; this.getList = function () { return this.list; }; this.passiveUpdate = function (data) { this.failedCount = 0; this.list.assignJsonData(data); }; this.init(); }; const SinglePage = function () { this.modules = []; }; const Module = function (chartContainerSelector, dataCtlName) { this.selector = chartContainerSelector; this.dataCtl = dataCtlName; this.activeData = null; this.lastActive = 0; this.tickInterval = 1000; /** * * bindData to UI * @param data DataObjectList */ this.setData = function (data) { if (data.ctlName === this.dataCtl) { if(showNetwork) console.log(`-------- Module ${this.selector} got data ----------- `); this.activeData = data; this.drawData(this.activeData); } else { if(showNetwork) console.log(`-------- Module ${this.selector} cannot use data of ${data.ctlName} ----------- `); } }; this.init = function () { // do init this.setupInterval(); }; this.tick = function () { // do tick }; this.setupInterval = function () { // do tick if (this.tickInterval !== 0) clearInterval(this.tickInterval); this.tickInterval = setInterval(this.tick, this.tickInterval, this); }; this.drawData = function () { // do drawData }; };