@visactor/vchart
Version:
charts lib based @visactor/VGrammar
230 lines (226 loc) • 12.1 kB
JavaScript
import { isNil, isValidNumber } from "@visactor/vutils";
import { calcLayoutNumber, calcPadding, normalizeLayoutPaddingSpec, boundsInRect } from "../util/space";
import { LayoutLevel, DEFAULT_LAYOUT_RECT_LEVEL, USER_LAYOUT_RECT_LEVEL } from "../constant/layout";
export class LayoutItem {
getSpec() {
return this._spec || {};
}
getLayoutStartPoint() {
return this._layoutStartPoint;
}
get layoutRectLevelMap() {
return this._layoutRectLevelMap;
}
get minWidth() {
return this._minWidth;
}
set minWidth(v) {
this._minWidth = v;
}
get maxWidth() {
return this._maxWidth;
}
set maxWidth(v) {
this._maxWidth = v;
}
get minHeight() {
return this._minHeight;
}
set minHeight(v) {
this._minHeight = v;
}
get maxHeight() {
return this._maxHeight;
}
set maxHeight(v) {
this._maxHeight = v;
}
get lastComputeRect() {
return this._lastComputeRect;
}
getLastComputeOutBounds() {
return this._lastComputeOutBounds;
}
get layoutOrient() {
return this._layoutOrient;
}
set layoutOrient(v) {
this._layoutOrient = v;
}
get model() {
return this._model;
}
get type() {
return this._model.type;
}
get willLayoutTag() {
return this._willLayoutTag;
}
constructor(model, option) {
var _a;
this.layoutClip = !1, this.autoIndent = !1, this._layoutStartPoint = {
x: 0,
y: 0
}, this._layoutRect = {
width: 0,
height: 0
}, this._layoutRectLevelMap = {
width: DEFAULT_LAYOUT_RECT_LEVEL,
height: DEFAULT_LAYOUT_RECT_LEVEL
}, this._minWidth = null, this._maxWidth = null, this._minHeight = null, this._maxHeight = null,
this._lastComputeRect = null, this._lastComputeOutBounds = {
x1: 0,
x2: 0,
y1: 0,
y2: 0
}, this.getLayoutRect = () => this._layoutRect, this.layoutType = "normal", this._layoutOrient = "left",
this.layoutPaddingLeft = 0, this.layoutPaddingTop = 0, this.layoutPaddingRight = 0,
this.layoutPaddingBottom = 0, this.layoutOffsetX = 0, this.layoutOffsetY = 0, this.layoutLevel = LayoutLevel.Region,
this._willLayoutTag = !0, this._model = model, this._option = option, this.layoutLevel = option.layoutLevel,
this.layoutType = option.layoutType, option.layoutOrient && (this.layoutOrient = option.layoutOrient),
this._spec = null === (_a = null == model ? void 0 : model.getSpec) || void 0 === _a ? void 0 : _a.call(model);
}
_setLayoutAttributeFromSpec(spec, chartViewRect) {
var _a, _b, _c, _d;
if (this._spec && !1 !== this._spec.visible) {
const padding = normalizeLayoutPaddingSpec(spec.padding);
let paddingValue = calcPadding(padding, chartViewRect, chartViewRect);
this._option.transformLayoutPadding && (paddingValue = this._option.transformLayoutPadding(paddingValue)),
this.layoutPaddingLeft = paddingValue.left, this.layoutPaddingRight = paddingValue.right,
this.layoutPaddingTop = paddingValue.top, this.layoutPaddingBottom = paddingValue.bottom,
this._minHeight = isNil(spec.minHeight) ? null !== (_a = this._minHeight) && void 0 !== _a ? _a : null : calcLayoutNumber(spec.minHeight, chartViewRect.height, chartViewRect),
this._maxHeight = isNil(spec.maxHeight) ? null !== (_b = this._maxHeight) && void 0 !== _b ? _b : null : calcLayoutNumber(spec.maxHeight, chartViewRect.height, chartViewRect),
this._minWidth = isNil(spec.minWidth) ? null !== (_c = this._minWidth) && void 0 !== _c ? _c : null : calcLayoutNumber(spec.minWidth, chartViewRect.width, chartViewRect),
this._maxWidth = isNil(spec.maxWidth) ? null !== (_d = this._maxWidth) && void 0 !== _d ? _d : null : calcLayoutNumber(spec.maxWidth, chartViewRect.width, chartViewRect),
spec.width && this.setLayoutRect({
width: calcLayoutNumber(spec.width, chartViewRect.width, chartViewRect)
}, {
width: USER_LAYOUT_RECT_LEVEL
}), spec.height && this.setLayoutRect({
height: calcLayoutNumber(spec.height, chartViewRect.height, chartViewRect)
}, {
height: USER_LAYOUT_RECT_LEVEL
}), isNil(spec.offsetX) || (this.layoutOffsetX = calcLayoutNumber(spec.offsetX, chartViewRect.width, chartViewRect)),
isNil(spec.offsetY) || (this.layoutOffsetY = calcLayoutNumber(spec.offsetY, chartViewRect.height, chartViewRect)),
spec.alignSelf && (this.alignSelf = spec.alignSelf);
}
}
setAttrFromSpec(spec, chartViewRect) {
var _a, _b, _c, _d;
this._spec = spec, this.layoutType = null !== (_a = spec.layoutType) && void 0 !== _a ? _a : this.layoutType,
this.layoutLevel = null !== (_b = spec.layoutLevel) && void 0 !== _b ? _b : this.layoutLevel,
this.layoutOrient = null !== (_c = spec.orient) && void 0 !== _c ? _c : this.layoutOrient,
this._setLayoutAttributeFromSpec(spec, chartViewRect), this.layoutClip = null !== (_d = spec.clip) && void 0 !== _d ? _d : this.layoutClip;
}
onLayoutStart(layoutRect, viewRect) {
this._setLayoutAttributeFromSpec(this._spec, viewRect);
}
onLayoutEnd() {}
_getAbsoluteSpecValue(layoutRect) {
const result = {
top: null,
bottom: null,
left: null,
right: null
};
return [ "top", "bottom", "left", "right" ].forEach((k => {
isNil(this._spec[k]) || (result[k] = calcLayoutNumber(this._spec[k], "top" === k || "bottom" === k ? layoutRect.height : layoutRect.width, layoutRect));
})), result;
}
absoluteLayoutInRect(layoutRect) {
const {top: top, bottom: bottom, left: left, right: right} = this._getAbsoluteSpecValue(layoutRect), layoutSize = {
width: layoutRect.width - this.layoutPaddingLeft - this.layoutPaddingRight,
height: layoutRect.height - this.layoutPaddingTop - this.layoutPaddingBottom
};
isNil(left) || (layoutSize.width -= left), isNil(right) || (layoutSize.width -= right),
isNil(top) || (layoutSize.height -= top), isNil(bottom) || (layoutSize.height -= bottom),
this.setLayoutRect(layoutSize);
const {width: width, height: height} = this.computeBoundsInRect(this.getLayoutRect());
this.setLayoutRect({
width: width,
height: height
});
const pos = {
x: layoutRect.x,
y: layoutRect.y
};
!0 === this._spec.center ? (pos.x = layoutRect.x + .5 * layoutRect.width - .5 * width,
pos.y = layoutRect.y + .5 * layoutRect.height - .5 * height) : (isNil(left) ? isNil(right) || (pos.x = layoutRect.x + layoutRect.width - this.layoutPaddingRight - right - width) : pos.x = layoutRect.x + left + this.layoutPaddingLeft,
isNil(top) ? isNil(bottom) || (pos.y = layoutRect.y + layoutRect.height - this.layoutPaddingBottom - bottom - height) : pos.y = layoutRect.y + top + this.layoutPaddingTop),
this.setLayoutStartPosition(pos);
}
setLayoutStartPosition(pos) {
var _a, _b;
this._option.transformLayoutPosition && (pos = this._option.transformLayoutPosition(pos)),
isValidNumber(pos.x) && (this._layoutStartPoint.x = pos.x), isValidNumber(pos.y) && (this._layoutStartPoint.y = pos.y),
null === (_b = (_a = this._model).afterSetLayoutStartPoint) || void 0 === _b || _b.call(_a, this._layoutStartPoint);
}
setLayoutRect({width: width, height: height}, levelMap) {
var _a, _b, _c, _d;
isValidNumber(width) && (null !== (_a = null == levelMap ? void 0 : levelMap.width) && void 0 !== _a ? _a : DEFAULT_LAYOUT_RECT_LEVEL) >= this._layoutRectLevelMap.width && (this._layoutRect.width = width,
this._layoutRectLevelMap.width = null !== (_b = null == levelMap ? void 0 : levelMap.width) && void 0 !== _b ? _b : DEFAULT_LAYOUT_RECT_LEVEL),
isValidNumber(height) && (null !== (_c = null == levelMap ? void 0 : levelMap.height) && void 0 !== _c ? _c : DEFAULT_LAYOUT_RECT_LEVEL) >= this._layoutRectLevelMap.height && (this._layoutRect.height = height,
this._layoutRectLevelMap.height = null !== (_d = null == levelMap ? void 0 : levelMap.height) && void 0 !== _d ? _d : DEFAULT_LAYOUT_RECT_LEVEL),
this.setRectInSpec(this._layoutRect);
}
getLayout() {
return {
x: this._layoutStartPoint.x,
y: this._layoutStartPoint.y,
width: this._layoutRect.width,
height: this._layoutRect.height
};
}
mergeLayoutRect({width: width, height: height}) {
const rect = {
width: width,
height: height
};
return this._layoutRectLevelMap.width > DEFAULT_LAYOUT_RECT_LEVEL && (rect.width = this._layoutRect.width),
this._layoutRectLevelMap.height > DEFAULT_LAYOUT_RECT_LEVEL && (rect.height = this._layoutRect.height),
rect;
}
getOrientPosAttribute() {
return "bottom" === this._layoutOrient || "top" === this._layoutOrient ? "x" : "y";
}
getOrientSizeAttribute() {
return "bottom" === this._layoutOrient || "top" === this._layoutOrient ? "width" : "height";
}
changeBoundsBySetting(bounds) {
return this._layoutRectLevelMap.width > DEFAULT_LAYOUT_RECT_LEVEL && (bounds.x2 = bounds.x1 + this._layoutRect.width),
this._layoutRectLevelMap.height > DEFAULT_LAYOUT_RECT_LEVEL && (bounds.y2 = bounds.y1 + this._layoutRect.height),
bounds.x1 -= this._layoutStartPoint.x, bounds.x2 -= this._layoutStartPoint.x, bounds.y1 -= this._layoutStartPoint.y,
bounds.y2 -= this._layoutStartPoint.y, bounds;
}
setRectInSpec(rect) {
const result = Object.assign({}, rect);
return this._layoutRectLevelMap.width < USER_LAYOUT_RECT_LEVEL ? (isNil(this._minWidth) || (result.width = Math.max(result.width, this._minWidth)),
isNil(this._maxWidth) || (result.width = Math.min(result.width, this._maxWidth))) : result.width = this._layoutRect.width,
this._layoutRectLevelMap.height < USER_LAYOUT_RECT_LEVEL ? (isNil(this._minHeight) || (result.height = Math.max(result.height, this._minHeight)),
isNil(this._maxHeight) || (result.height = Math.min(result.height, this._maxHeight))) : result.height = this._layoutRect.height,
result;
}
computeBoundsInRect(rect) {
if (this._lastComputeRect = rect, !("region-relative" !== this.layoutType && "region-relative-overlap" !== this.layoutType || (this._layoutRectLevelMap.width !== USER_LAYOUT_RECT_LEVEL || "left" !== this.layoutOrient && "right" !== this.layoutOrient) && (this._layoutRectLevelMap.height !== USER_LAYOUT_RECT_LEVEL || "bottom" !== this.layoutOrient && "top" !== this.layoutOrient))) return this._layoutRect;
const bounds = Object.assign({}, this._model.getBoundsInRect(this.setRectInSpec(rect), rect));
this.changeBoundsBySetting(bounds), this.autoIndent && bounds.x2 - bounds.x1 > 0 && bounds.y2 - bounds.y1 > 0 && (this._lastComputeOutBounds.x1 = Math.ceil(-bounds.x1),
this._lastComputeOutBounds.x2 = Math.ceil(bounds.x2 - rect.width), this._lastComputeOutBounds.y1 = Math.ceil(-bounds.y1),
this._lastComputeOutBounds.y2 = Math.ceil(bounds.y2 - rect.height));
let result = this.setRectInSpec(boundsInRect(bounds, rect));
return this._option.transformLayoutRect && (result = this._option.transformLayoutRect(result)),
result;
}
getModelId() {
return this._model.id;
}
getModelVisible() {
return this._model.getVisible();
}
setWillLayoutTag() {
this._willLayoutTag = !0;
}
clearWillLayoutTag() {
this._willLayoutTag = !1;
}
}
//# sourceMappingURL=layout-item.js.map