@antv/f2
Version:
Charts for mobile visualization.
206 lines • 6.69 kB
JavaScript
import { __assign, __extends } from "tslib";
import { jsx, Component, computeLayout } from '@antv/f-engine';
import { isFunction } from '@antv/util';
export default (function (View) {
return /** @class */function (_super) {
__extends(Legend, _super);
function Legend(props) {
var _this = _super.call(this, props) || this;
_this._onclick = function (item) {
var _a;
var props = _this.props;
var chart = props.chart,
_b = props.clickable,
clickable = _b === void 0 ? true : _b,
onClick = props.onClick;
if (!clickable) return;
var clickItem = item.currentTarget;
if (!clickItem) {
return;
}
// @ts-ignore
var dataItem = clickItem.config['data-item'];
if (!dataItem) {
return;
}
if (isFunction(onClick)) {
onClick(dataItem);
}
var field = dataItem.field,
tickValue = dataItem.tickValue;
var prevFiltered = _this.state.filtered;
var filtered = __assign(__assign({}, prevFiltered), (_a = {}, _a[tickValue] = !prevFiltered[tickValue], _a));
_this.setState({
filtered: filtered
});
chart.filter(field, function (value) {
return !filtered[value];
});
};
_this.state = {
filtered: {},
items: []
};
return _this;
}
Legend.prototype.getOriginItems = function () {
var chart = this.props.chart;
return chart.getLegendItems();
};
Legend.prototype.getItems = function () {
var _a;
var _b = this,
props = _b.props,
state = _b.state;
var filtered = state.filtered;
var renderItems = ((_a = props.items) === null || _a === void 0 ? void 0 : _a.length) ? props.items : this.getOriginItems();
if (!renderItems) return null;
return renderItems.map(function (item) {
var tickValue = item.tickValue;
return __assign(__assign({}, item), {
filtered: filtered[tickValue]
});
});
};
Legend.prototype.setItems = function (items) {
this.setState({
items: items
});
};
Legend.prototype.getMaxItemBox = function (node) {
var maxItemWidth = 0;
var maxItemHeight = 0;
(node.children || []).forEach(function (child) {
var layout = child.layout;
var width = layout.width,
height = layout.height;
maxItemWidth = Math.max(maxItemWidth, width);
maxItemHeight = Math.max(maxItemHeight, height);
});
return {
width: maxItemWidth,
height: maxItemHeight
};
};
// 计算 legend 的位置
Legend.prototype._init = function () {
var _a = this,
props = _a.props,
context = _a.context;
var
// @ts-ignore
parentLayout = props.layout,
customWidth = props.width,
customHeight = props.height,
_b = props.position,
position = _b === void 0 ? 'top' : _b;
var items = this.getItems();
if (!items || !items.length) return;
var left = parentLayout.left,
top = parentLayout.top,
layoutWidth = parentLayout.width,
layoutHeight = parentLayout.height;
var width = context.px2hd(customWidth) || layoutWidth;
var node = computeLayout(this, this.render());
var _c = this.getMaxItemBox(node),
itemMaxWidth = _c.width,
itemMaxHeight = _c.height;
// 每行最多的个数
var lineMaxCount = Math.max(1, Math.floor(width / itemMaxWidth));
var itemCount = items.length;
// legend item 的行数
var lineCount = Math.ceil(itemCount / lineMaxCount);
var itemWidth = width / lineMaxCount;
var autoHeight = itemMaxHeight * lineCount;
var style = {
left: left,
top: top,
width: width,
// height 默认自适应
height: undefined,
flexDirection: 'row',
flexWrap: 'wrap',
alignItems: 'center',
justifyContent: 'flex-start'
};
// 如果只有一行,2端对齐
if (lineCount === 1) {
style.justifyContent = 'space-between';
}
if (position === 'top') {
style.height = customHeight ? customHeight : autoHeight;
}
if (position === 'left') {
style.flexDirection = 'column';
style.justifyContent = 'center';
style.width = itemMaxWidth;
style.height = customHeight ? customHeight : layoutHeight;
}
if (position === 'right') {
style.flexDirection = 'column';
style.alignItems = 'flex-start';
style.justifyContent = 'center';
style.width = itemMaxWidth;
style.height = customHeight ? customHeight : layoutHeight;
style.left = left + (width - itemMaxWidth);
}
if (position === 'bottom') {
style.top = top + (layoutHeight - autoHeight);
style.height = customHeight ? customHeight : autoHeight;
}
this.itemWidth = itemWidth;
this.legendStyle = style;
};
Legend.prototype.updateCoord = function () {
var _a = this,
context = _a.context,
props = _a.props,
legendStyle = _a.legendStyle;
var _b = props.position,
position = _b === void 0 ? 'top' : _b,
_c = props.margin,
margin = _c === void 0 ? '30px' : _c,
chart = props.chart;
var width = legendStyle.width,
height = legendStyle.height;
var marginNumber = context.px2hd(margin);
chart.updateCoordFor(this, {
position: position,
width: width + marginNumber,
height: height + marginNumber
});
};
Legend.prototype.willMount = function () {
var items = this.getItems();
if (!items || !items.length) return;
this._init();
this.updateCoord();
};
Legend.prototype.didMount = function () {
// this._initEvent();
};
Legend.prototype.willUpdate = function () {
var items = this.getItems();
if (!items || !items.length) return;
this._init();
this.updateCoord();
};
Legend.prototype.render = function () {
var _a = this,
props = _a.props,
itemWidth = _a.itemWidth,
legendStyle = _a.legendStyle;
var items = this.getItems();
if (!items || !items.length) {
return null;
}
return jsx(View, __assign({}, props, {
items: items,
itemWidth: itemWidth,
style: __assign(__assign({}, legendStyle), props.style),
onClick: this._onclick
}));
};
return Legend;
}(Component);
});