@visactor/vtable
Version:
canvas table width high performance
176 lines (171 loc) • 7.89 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: !0
}), exports.NumberRangeMap = void 0;
const vutils_1 = require("@visactor/vutils");
class NumberRangeMap {
constructor(table) {
this.isUpdate = !1, this._keys = [], this._sorted = !1, this.data = new Map, this._keys.length = 0,
this.cumulativeSum = new Map, this.difference = new Map, this.totalSum = 0, this.table = table;
}
get length() {
return this.data.size;
}
clear() {
this._keys = [], this.data.clear(), this.cumulativeSum.clear(), this.difference.clear(),
this.totalSum = 0;
}
clearRange() {
this.cumulativeSum.clear(), this.difference.clear();
}
add(position, value) {
if (!(0, vutils_1.isValid)(value)) return;
const defaultValue = this.table.getRowHeight(position);
this.data.has(position) || (this._keys.push(position), this._sorted = !1), this.data.set(position, value),
this.totalSum += value, this.updateDifference(position, value - defaultValue);
}
remove(position) {
if (this.data.has(position)) {
const value = this.data.get(position);
this.data.delete(position);
const index = this._keys.indexOf(position);
-1 !== index && this._keys.splice(index, 1), this.totalSum -= value;
const defaultValue = this.table.getRowHeight(position);
this.updateDifference(position, defaultValue - value);
}
}
put(position, newValue) {
if ((0, vutils_1.isValid)(newValue)) if (this.data.has(position)) {
const oldValue = this.data.get(position);
if (oldValue === newValue) return;
this.data.set(position, newValue);
const difference = newValue - oldValue;
this.totalSum += difference, this.updateDifference(position, difference);
} else this.add(position, newValue);
}
get(position) {
return this.data.get(position);
}
has(position) {
return this.data.has(position);
}
_sort() {
const {_keys: keys} = this;
this._sorted || (keys.sort(((a, b) => a < b ? -1 : a > b ? 1 : 0)), this._sorted = !0);
}
updateDifference(position, difference) {
var _a;
const oldDifference = null !== (_a = this.difference.get(position)) && void 0 !== _a ? _a : 0;
this.difference.set(position, oldDifference + difference), this.update();
}
getSumInRange(start, end) {
return this.calculatePrefixSum(end) - this.calculatePrefixSum(start - 1);
}
updateCumulativeSum(position, difference) {
for (const [pos, sum] of this.cumulativeSum) pos >= position && this.cumulativeSum.set(pos, sum + difference);
}
calculatePrefixSum(position) {
if (position < 0) return 0;
if (this.cumulativeSum.has(position)) {
let cache = this.cumulativeSum.get(position);
for (const [pos, difference] of this.difference) pos <= position && (cache += difference);
return cache;
}
return this.dealDiffenence(), this.getCumulativeSum(position);
}
getCumulativeSum(position) {
var _a;
let sum = 0;
for (let i = position; i >= 0; i--) {
if (this.cumulativeSum.has(i)) {
sum += this.cumulativeSum.get(i);
break;
}
sum += null !== (_a = this.data.get(i)) && void 0 !== _a ? _a : this.table.getRowHeight(i);
}
return this.cumulativeSum.set(position, sum), sum;
}
update() {
this.isUpdate || (this.isUpdate = !0, setTimeout((() => {
this.dealDiffenence(), this.isUpdate = !1;
}), 0));
}
dealDiffenence() {
for (const [sumPos] of this.cumulativeSum) for (const [difPos, difference] of this.difference) if (sumPos >= difPos) {
const oldSum = this.cumulativeSum.get(sumPos);
this.cumulativeSum.set(sumPos, oldSum + difference);
}
this.difference.clear();
}
insert(position, value) {
for (let i = position; i <= this.getLastIndex(); i++) this.cumulativeSum.delete(i);
const lastIndex = this.getLastIndex() + 1;
this.adjustOrder(position, position + 1, lastIndex - position), (0, vutils_1.isValid)(value) && this.put(position, value);
}
getLastIndex() {
return this._sort(), this._keys[this._keys.length - 1];
}
delLast() {
const lastIndex = this.getLastIndex();
this.remove(lastIndex);
}
delete(position) {
if (!this.has(position)) return;
for (let i = position; i <= this.getLastIndex(); i++) this.cumulativeSum.delete(i);
const lastIndex = this.getLastIndex();
this.adjustOrder(position + 1, position, lastIndex - position), this.delLast();
}
adjustOrder(sourceIndex, targetIndex, moveCount) {
this.clearRange(), this._sort();
const {_keys: keys} = this;
if (sourceIndex > targetIndex) {
const sourceVals = [];
for (let i = indexFirst(keys, sourceIndex + moveCount - 1); i >= 0; i--) {
const key = keys[i];
if (key >= sourceIndex) sourceVals.push(this.get(key)); else if (targetIndex <= key && key < sourceIndex) this.put(key + moveCount, this.get(key)); else if (key < targetIndex) break;
}
for (let i = 0; i < moveCount; i++) this.put(targetIndex + i, sourceVals[moveCount - 1 - i]);
}
const {length: length} = keys;
if (sourceIndex < targetIndex) {
const sourceVals = [];
for (let i = indexFirst(keys, sourceIndex); i < length; i++) {
const key = keys[i];
if (key >= sourceIndex && key < sourceIndex + moveCount) sourceVals.push(this.get(key)); else if (sourceIndex + moveCount <= key && key <= targetIndex) this.put(key - moveCount, this.get(key)); else if (key > targetIndex) break;
}
for (let i = 0; i < moveCount; i++) this.put(targetIndex + i, sourceVals[i]);
}
}
exchangeOrder(sourceIndex, sourceCount, targetIndex, targetCount, insertIndex) {
const {_keys: keys} = this;
if (this._sorted || (keys.sort(((a, b) => a < b ? -1 : a > b ? 1 : 0)), this._sorted = !0),
sourceIndex > targetIndex) {
const targetVals = [], sourceVals = [];
for (let i = indexFirst(keys, targetIndex); i < indexFirst(keys, sourceIndex) + sourceCount; i++) {
const key = keys[i];
key >= sourceIndex && key < sourceIndex + sourceCount ? sourceVals.push(this.get(key)) : targetVals.push(this.get(key));
}
for (let i = 0; i < sourceCount; i++) this.put(insertIndex + i, sourceVals[i]);
for (let i = 0; i < targetVals.length; i++) this.put(insertIndex + sourceCount + i, targetVals[i]);
} else {
const targetVals = [], sourceVals = [];
for (let i = indexFirst(keys, sourceIndex); i < indexFirst(keys, targetIndex) + targetCount; i++) {
const key = keys[i];
key >= sourceIndex && key < sourceIndex + sourceCount ? sourceVals.push(this.get(key)) : targetVals.push(this.get(key));
}
for (let i = 0; i < sourceCount; i++) this.put(insertIndex + i, sourceVals[i]);
for (let i = 0; i < targetVals.length; i++) this.put(sourceIndex + i, targetVals[i]);
}
}
}
function indexFirst(arr, elm) {
let low = 0, high = arr.length - 1;
for (;low <= high; ) {
const i = Math.floor((low + high) / 2);
if (arr[i] === elm) return i;
arr[i] > elm ? high = i - 1 : low = i + 1;
}
return high < 0 ? 0 : high;
}
//# sourceMappingURL=row-height-map.js.map
exports.NumberRangeMap = NumberRangeMap;