@revolist/revogrid
Version:
Virtual reactive data grid spreadsheet component - RevoGrid.
177 lines (176 loc) • 6.49 kB
JavaScript
/*!
* Built by Revolist OU ❤️
*/
import reduce from "lodash/reduce";
import debounce from "lodash/debounce";
import { RESIZE_INTERVAL } from "../utils/consts";
import { columnTypes, rowTypes, getItemByIndex, DimensionStore, gatherTrimmedItems, } from "../store/index";
import { getColumnSizes } from "../utils/column.utils";
/**
* Dimension provider
* Stores dimension information and custom sizes
*
* @dependsOn ViewportProvider
*/
export default class DimensionProvider {
constructor(viewports, config) {
this.viewports = viewports;
const sizeChanged = debounce((k) => config.realSizeChanged(k), RESIZE_INTERVAL);
this.stores = reduce([...rowTypes, ...columnTypes], (sources, t) => {
sources[t] = new DimensionStore(t);
sources[t].store.onChange('realSize', () => sizeChanged(t));
return sources;
}, {});
}
/**
* Clear old sizes from dimension and viewports
* @param type - dimension type
* @param count - count of items
*/
clearSize(t, count) {
this.stores[t].drop();
// after we done with drop trigger viewport recalculaction
this.viewports.stores[t].setOriginalSizes(this.stores[t].store.get('originItemSize'));
this.setItemCount(count, t);
}
/**
* Apply new custom sizes to dimension and view port
* @param type - dimension type
* @param sizes - new custom sizes
* @param keepOld - keep old sizes merge new with old
*/
setCustomSizes(type, sizes, keepOld = false) {
let newSizes = sizes;
if (keepOld) {
const oldSizes = this.stores[type].store.get('sizes');
newSizes = Object.assign(Object.assign({}, oldSizes), sizes);
}
this.stores[type].setDimensionSize(newSizes);
this.setViewPortCoordinate({
type,
force: true,
});
}
setItemCount(realCount, type) {
this.viewports.stores[type].setViewport({ realCount });
this.stores[type].setStore({ count: realCount });
}
/**
* Apply trimmed items
* @param trimmed - trimmed items
* @param type
*/
setTrimmed(trimmed, type) {
const allTrimmed = gatherTrimmedItems(trimmed);
const dimStoreType = this.stores[type];
dimStoreType.setStore({ trimmed: allTrimmed });
this.setViewPortCoordinate({
type,
force: true,
});
}
/**
* Sets dimension data and viewport coordinate
* @param itemCount
* @param type - dimension type
* @param noVirtual - disable virtual data
*/
setData(itemCount, type, noVirtual = false) {
this.setItemCount(itemCount, type);
// Virtualization will get disabled
if (noVirtual) {
const dimension = this.stores[type].getCurrentState();
this.viewports.stores[type].setViewport({
virtualSize: dimension.realSize,
});
}
this.setViewPortCoordinate({
type,
});
}
/**
* Applies new columns to the dimension provider
* @param columns - new columns data
* @param disableVirtualX - disable virtual data for X axis
*/
applyNewColumns(columns, disableVirtualX, keepOld = false) {
// Apply new columns to dimension provider
for (let type of columnTypes) {
if (!keepOld) {
// Clear existing data in the dimension provider
this.stores[type].drop();
}
// Get the new columns for the current type
const items = columns[type];
// Determine if virtual data should be disabled for the current type
const noVirtual = type !== 'rgCol' || disableVirtualX;
// Set the items count in the dimension provider
this.stores[type].setStore({ count: items.length });
// Set the custom sizes for the columns
const newSizes = getColumnSizes(items);
this.stores[type].setDimensionSize(newSizes);
// Update the viewport with new data
const vpUpdate = {
// This triggers drop on realCount change
realCount: items.length,
};
// If virtual data is disabled, set the virtual size to the real size
if (noVirtual) {
vpUpdate.virtualSize = this.stores[type].getCurrentState().realSize;
}
// Update the viewport
this.viewports.stores[type].setViewport(vpUpdate);
this.setViewPortCoordinate({
type,
});
}
}
/**
* Gets the full size of the grid by summing up the sizes of all dimensions
* Goes through all dimensions columnTypes (x) and rowTypes (y) and sums up their sizes
*/
getFullSize() {
var _a, _b;
let x = 0;
let y = 0;
for (let type of columnTypes) {
x += ((_a = this.stores[type]) === null || _a === void 0 ? void 0 : _a.store.get('realSize')) || 0;
}
for (let type of rowTypes) {
y += ((_b = this.stores[type]) === null || _b === void 0 ? void 0 : _b.store.get('realSize')) || 0;
}
return { y, x };
}
setViewPortCoordinate({ type, coordinate = this.viewports.stores[type].lastCoordinate, force = false, }) {
const dimension = this.stores[type].getCurrentState();
this.viewports.stores[type].setViewPortCoordinate(coordinate, dimension, force);
}
getViewPortPos(e) {
const dimension = this.stores[e.dimension].getCurrentState();
const item = getItemByIndex(dimension, e.coordinate);
return item.start;
}
setSettings(data, dimensionType) {
let stores = [];
switch (dimensionType) {
case 'rgCol':
stores = columnTypes;
break;
case 'rgRow':
stores = rowTypes;
break;
}
for (let s of stores) {
this.stores[s].setStore(data);
}
}
updateSizesPositionByNewDataIndexes(type, newItemsOrder, prevItemsOrder = []) {
// Move custom sizes to new order
this.stores[type].updateSizesPositionByIndexes(newItemsOrder, prevItemsOrder);
this.setViewPortCoordinate({
type,
force: true,
});
}
}
//# sourceMappingURL=dimension.provider.js.map