@visactor/vchart
Version:
charts lib based @visactor/VGrammar
186 lines (180 loc) • 10.4 kB
JavaScript
import { isFunction, isValid, isValidNumber } from "@visactor/vutils";
import { Factory } from "../../core/factory";
export class GridLayout {
constructor(gridInfo, ctx) {
this._chartLayoutRect = {
x: 0,
y: 0,
width: 1,
height: 1
}, this._col = 1, this._row = 1, this._elementMap = new Map, this.standardizationSpec(gridInfo),
this._gridInfo = gridInfo, this._col = gridInfo.col, this._row = gridInfo.row, this._colSize = new Array(this._col).fill(null),
this._rowSize = new Array(this._row).fill(null), this._colElements = new Array(this._col).fill([]),
this._rowElements = new Array(this._row).fill([]), this._onError = null == ctx ? void 0 : ctx.onError,
this.initUserSetting();
}
standardizationSpec(gridInfo) {
var _a, _b, _c;
gridInfo.col = null !== (_a = gridInfo.col) && void 0 !== _a ? _a : 1, gridInfo.row = null !== (_b = gridInfo.row) && void 0 !== _b ? _b : 1,
gridInfo.elements = null !== (_c = gridInfo.elements) && void 0 !== _c ? _c : [];
}
initUserSetting() {
this._gridInfo.colWidth && this.setSizeFromUserSetting(this._gridInfo.colWidth, this._colSize, this._col, this._chartLayoutRect.width),
this._gridInfo.rowHeight && this.setSizeFromUserSetting(this._gridInfo.rowHeight, this._rowSize, this._row, this._chartLayoutRect.height),
this._colSize.forEach(((c, i) => {
c || (this._colSize[i] = {
value: 0,
isUserSetting: !1,
isLayoutSetting: !1
});
})), this._rowSize.forEach(((r, i) => {
r || (this._rowSize[i] = {
value: 0,
isUserSetting: !1,
isLayoutSetting: !1
});
}));
}
setSizeFromUserSetting(userSetting, gridSize, gridMax, maxSize) {
userSetting.forEach((userSet => {
userSet.index < 0 && userSet.index >= gridMax || (isValidNumber(userSet.size) ? gridSize[userSet.index] = {
value: +userSet.size,
isUserSetting: !0,
isLayoutSetting: !1
} : isFunction(userSet.size) && (gridSize[userSet.index] = {
value: userSet.size(maxSize),
isUserSetting: !0,
isLayoutSetting: !1
}));
}));
}
clearLayoutSize() {
this._gridInfo.colWidth && this.setSizeFromUserSetting(this._gridInfo.colWidth, this._colSize, this._col, this._chartLayoutRect.width),
this._gridInfo.rowHeight && this.setSizeFromUserSetting(this._gridInfo.rowHeight, this._rowSize, this._row, this._chartLayoutRect.height),
this._colSize.forEach((c => {
c.isLayoutSetting = !1, c.isUserSetting || (c.value = 0);
})), this._rowSize.forEach((r => {
r.isLayoutSetting = !1, r.isUserSetting || (r.value = 0);
}));
}
getItemGridInfo(item) {
var _a;
const mapResult = this._elementMap.get(item);
if (mapResult) return mapResult;
let result;
return result = null === (_a = this._gridInfo.elements) || void 0 === _a ? void 0 : _a.find((e => {
var _a;
if ("modelId" in e && isValid(e.modelId)) {
if (isValid(item.model.userId) && item.model.userId === e.modelId) return !0;
} else if ("modelKey" in e && isValid(e.modelKey) && "modelIndex" in e && isValid(e.modelIndex)) {
if ((null !== (_a = item.model.specKey) && void 0 !== _a ? _a : item.model.type) === e.modelKey && item.model.getSpecIndex() === e.modelIndex) return !0;
}
return !1;
})), result || (result = {
col: 0,
colSpan: 1,
row: 0,
rowSpan: 1
}), this._elementMap.set(item, result), result;
}
getSizeFromGrid(spec, type) {
var _a;
const sizeList = "col" === type ? this._colSize : this._rowSize;
let result = 0;
for (let index = spec[type]; index < spec[type] + (null !== (_a = spec[`${type}Span`]) && void 0 !== _a ? _a : 1); index++) result += sizeList[index].value;
return result;
}
getSizeFromUser(spec, type) {
var _a, _b;
const sizeList = "col" === type ? this._colSize : this._rowSize;
if (!(null === (_a = sizeList[spec[type]]) || void 0 === _a ? void 0 : _a.isUserSetting)) return;
let result = 0;
for (let index = spec[type]; index < spec[type] + (null !== (_b = spec[`${type}Span`]) && void 0 !== _b ? _b : 1); index++) {
if (!sizeList[index].isUserSetting) return;
result += sizeList[index].value;
}
return result;
}
setItemLayoutSizeToGrid(item, gridSpec) {
if (isColItem(item)) {
if (gridSpec.colSpan && gridSpec.colSpan > 1) return;
if (this._colSize[gridSpec.col].isUserSetting) return;
this._colSize[gridSpec.col].value = Math.max(this._colSize[gridSpec.col].value, item.getLayoutRect().width + item.layoutPaddingLeft + item.layoutPaddingRight),
this._colSize[gridSpec.col].isLayoutSetting = !0;
} else {
if (gridSpec.rowSpan && gridSpec.rowSpan > 1) return;
if (this._rowSize[gridSpec.row].isUserSetting) return;
this._rowSize[gridSpec.row].value = Math.max(this._rowSize[gridSpec.row].value, item.getLayoutRect().height + item.layoutPaddingTop + item.layoutPaddingBottom),
this._rowSize[gridSpec.row].isLayoutSetting = !0;
}
}
layoutGrid(type) {
const gridSize = "col" === type ? this._colSize : this._rowSize;
let unSetSize = "col" === type ? this._chartLayoutRect.width : this._chartLayoutRect.height;
const willSize = [];
gridSize.forEach((s => {
s.isUserSetting || s.isLayoutSetting ? unSetSize -= s.value : willSize.push(s);
})), unSetSize < 0 && console.warn(`layout content ${type} size bigger than chart`),
willSize.forEach((s => s.value = unSetSize / willSize.length));
}
getItemPosition(item) {
const gridSpec = this.getItemGridInfo(item), point = {
x: this._chartLayoutRect.x,
y: this._chartLayoutRect.y
};
for (let col = 0; col < gridSpec.col; col++) point.x += this._colSize[col].value;
for (let row = 0; row < gridSpec.row; row++) point.y += this._rowSize[row].value;
return point.x += item.layoutPaddingLeft + item.layoutOffsetX, point.y += item.layoutPaddingTop + item.layoutOffsetY,
point;
}
getItemLayoutRect(item) {
var _a, _b;
const gridSpec = this.getItemGridInfo(item);
return {
width: (null !== (_a = this.getSizeFromGrid(gridSpec, "col")) && void 0 !== _a ? _a : this._chartLayoutRect.width) - item.layoutPaddingLeft - item.layoutPaddingRight,
height: (null !== (_b = this.getSizeFromGrid(gridSpec, "row")) && void 0 !== _b ? _b : this._chartLayoutRect.height) - item.layoutPaddingTop - item.layoutPaddingBottom
};
}
layoutItems(_chart, items, chartLayoutRect, chartViewBox) {
this._chartLayoutRect = chartLayoutRect, this._chartViewBox = chartViewBox, this.clearLayoutSize(),
items.sort(((a, b) => b.layoutLevel - a.layoutLevel));
const normalItems = items.filter((item => "normal" === item.layoutType && !1 !== item.getModelVisible())), normalItemsCol = normalItems.filter((item => isColItem(item))), normalItemsRow = normalItems.filter((item => !isColItem(item)));
normalItems.forEach((item => {
this.layoutOneItem(item, "user", !1);
}));
const regionsRelative = items.filter((x => "region-relative" === x.layoutType)), regionsRelativeCol = regionsRelative.filter((item => isColItem(item))), regionsRelativeRow = regionsRelative.filter((item => !isColItem(item)));
regionsRelativeCol.forEach((item => this.layoutOneItem(item, "user", !1))), this.layoutGrid("col"),
normalItemsRow.forEach((item => this.layoutOneItem(item, "colGrid", !1))), regionsRelativeRow.forEach((item => {
this.layoutOneItem(item, "colGrid", !1);
})), this.layoutGrid("row"), regionsRelativeRow.forEach((item => {
this.layoutOneItem(item, "grid", !1);
})), normalItemsCol.forEach((item => this.layoutOneItem(item, "grid", !1))), regionsRelativeCol.forEach((item => {
this.layoutOneItem(item, "grid", !0);
})), this.layoutGrid("col"), items.filter((x => "region" === x.layoutType)).forEach((item => this.layoutOneItem(item, "grid", !1))),
this.layoutAbsoluteItems(items.filter((x => "absolute" === x.layoutType))), items.filter((x => "absolute" !== x.layoutType)).forEach((item => {
item.setLayoutStartPosition(this.getItemPosition(item));
}));
}
layoutAbsoluteItems(absoluteItems) {
absoluteItems.forEach((item => {
item.absoluteLayoutInRect(this._chartLayoutRect);
}));
}
layoutOneItem(item, sizeType, ignoreTag) {
var _a, _b;
const sizeCallRow = "rowGrid" === sizeType || "grid" === sizeType ? this.getSizeFromGrid.bind(this) : this.getSizeFromUser.bind(this), sizeCallCol = "colGrid" === sizeType || "grid" === sizeType ? this.getSizeFromGrid.bind(this) : this.getSizeFromUser.bind(this), gridSpec = this.getItemGridInfo(item), computeRect = {
width: (null !== (_a = sizeCallCol(gridSpec, "col")) && void 0 !== _a ? _a : this._chartLayoutRect.width) - item.layoutPaddingLeft - item.layoutPaddingRight,
height: (null !== (_b = sizeCallRow(gridSpec, "row")) && void 0 !== _b ? _b : this._chartLayoutRect.height) - item.layoutPaddingTop - item.layoutPaddingBottom
}, rect = item.computeBoundsInRect(computeRect);
isValidNumber(rect.width) || (rect.width = computeRect.width), isValidNumber(rect.height) || (rect.height = computeRect.height),
item.setLayoutRect("grid" !== sizeType ? rect : computeRect), this.setItemLayoutSizeToGrid(item, gridSpec);
}
}
function isColItem(item) {
return "left" === item.layoutOrient || "right" === item.layoutOrient;
}
GridLayout.type = "grid";
export const registerGridLayout = () => {
Factory.registerLayout(GridLayout.type, GridLayout);
};
//# sourceMappingURL=grid-layout.js.map