@antv/f2
Version:
Charts for mobile visualization.
484 lines (483 loc) • 16.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _tslib = require("tslib");
var _fEngine = require("@antv/f-engine");
var _util = require("@antv/util");
// view 的默认配置
var defaultStyle = {
showTitle: false,
showCrosshairs: false,
crosshairsType: 'y',
crosshairsStyle: {
stroke: 'rgba(0, 0, 0, 0.25)',
lineWidth: '2px'
},
showTooltipMarker: false,
markerBackgroundStyle: {
fill: '#CCD6EC',
opacity: 0.3,
padding: '6px'
},
tooltipMarkerStyle: {
fill: '#fff',
lineWidth: '3px'
},
background: {
radius: '4px',
fill: 'rgba(0, 0, 0, 0.65)',
padding: ['6px', '10px']
},
titleStyle: {
fontSize: '24px',
fill: '#fff',
textAlign: 'start',
textBaseline: 'top'
},
nameStyle: {
fontSize: '24px',
fill: 'rgba(255, 255, 255, 0.65)',
textAlign: 'start',
textBaseline: 'middle'
},
valueStyle: {
fontSize: '24px',
fill: '#fff',
textAlign: 'start',
textBaseline: 'middle'
},
joinString: ': ',
showItemMarker: true,
itemMarkerStyle: {
width: '12px',
radius: '6px',
symbol: 'circle',
lineWidth: '2px',
stroke: '#fff'
},
layout: 'horizontal',
snap: false,
xTipTextStyle: {
fontSize: '24px',
fill: '#fff'
},
yTipTextStyle: {
fontSize: '24px',
fill: '#fff'
},
xTipBackground: {
radius: '4px',
fill: 'rgba(0, 0, 0, 0.65)',
padding: ['6px', '10px'],
marginLeft: '-50%',
marginTop: '6px'
},
yTipBackground: {
radius: '4px',
fill: 'rgba(0, 0, 0, 0.65)',
padding: ['6px', '10px'],
marginLeft: '-100%',
marginTop: '-50%'
}
};
function directionEnabled(mode, dir) {
if (mode === undefined) {
return true;
} else if (typeof mode === 'string') {
return mode.indexOf(dir) !== -1;
}
return false;
}
var RenderItemMarker = function RenderItemMarker(props) {
var records = props.records,
coord = props.coord,
context = props.context,
markerBackgroundStyle = props.markerBackgroundStyle;
var point = coord.convertPoint({
x: 1,
y: 1
});
var padding = context.px2hd(markerBackgroundStyle.padding || '6px');
var xPoints = (0, _tslib.__spreadArray)((0, _tslib.__spreadArray)([], records.map(function (record) {
return record.xMin;
}), true), records.map(function (record) {
return record.xMax;
}), true);
var yPoints = (0, _tslib.__spreadArray)((0, _tslib.__spreadArray)([], records.map(function (record) {
return record.yMin;
}), true), records.map(function (record) {
return record.yMax;
}), true);
if (coord.transposed) {
xPoints.push(point.x);
} else {
yPoints.push(point.y);
}
var xMin = Math.min.apply(null, xPoints);
var xMax = Math.max.apply(null, xPoints);
var yMin = Math.min.apply(null, yPoints);
var yMax = Math.max.apply(null, yPoints);
var x = coord.transposed ? xMin : xMin - padding;
var y = coord.transposed ? yMin - padding : yMin;
var width = coord.transposed ? xMax - xMin : xMax - xMin + 2 * padding;
var height = coord.transposed ? yMax - yMin + 2 * padding : yMax - yMin;
return (0, _fEngine.jsx)("rect", {
style: (0, _tslib.__assign)({
x: x,
y: y,
width: width,
height: height
}, markerBackgroundStyle)
});
};
var RenderCrosshairs = function RenderCrosshairs(props) {
var records = props.records,
coord = props.coord,
chart = props.chart,
crosshairsType = props.crosshairsType,
crosshairsStyle = props.crosshairsStyle,
xPositionType = props.xPositionType,
yPositionType = props.yPositionType;
var coordLeft = coord.left,
coordTop = coord.top,
coordRight = coord.right,
coordBottom = coord.bottom,
center = coord.center;
var firstRecord = records[0];
var x = firstRecord.x,
y = firstRecord.y,
origin = firstRecord.origin,
xField = firstRecord.xField,
coordData = firstRecord.coord;
if (coord.isPolar) {
// 极坐标下的辅助线
var xScale = chart.getScale(xField);
var ticks = xScale.getTicks();
var tick = (0, _util.find)(ticks, function (tick) {
return origin[xField] === tick.tickValue;
});
var end = coord.convertPoint({
x: tick.value,
y: 1
});
return (0, _fEngine.jsx)("line", {
style: (0, _tslib.__assign)({
x1: center.x,
y1: center.y,
x2: end.x,
y2: end.y
}, crosshairsStyle)
});
}
return (0, _fEngine.jsx)("group", null, directionEnabled(crosshairsType, 'x') ? (0, _fEngine.jsx)("line", {
style: (0, _tslib.__assign)({
x1: coordLeft,
y1: yPositionType === 'coord' ? coordData.y : y,
x2: coordRight,
y2: yPositionType === 'coord' ? coordData.y : y
}, crosshairsStyle)
}) : null, directionEnabled(crosshairsType, 'y') ? (0, _fEngine.jsx)("line", {
style: (0, _tslib.__assign)({
x1: xPositionType === 'coord' ? coordData.x : x,
y1: coordTop,
x2: xPositionType === 'coord' ? coordData.x : x,
y2: coordBottom
}, crosshairsStyle)
}) : null);
};
var RenderXTip = function RenderXTip(props) {
var records = props.records,
coord = props.coord,
xTip = props.xTip,
xPositionType = props.xPositionType,
xTipTextStyle = props.xTipTextStyle,
xTipBackground = props.xTipBackground;
var coordBottom = coord.bottom;
var firstRecord = records[0];
var x = firstRecord.x,
coordData = firstRecord.coord;
var xFirstText = firstRecord.name;
return (0, _fEngine.jsx)("rect", {
style: (0, _tslib.__assign)({
display: 'flex',
left: xPositionType === 'coord' ? coordData.x : x,
top: coordBottom
}, xTipBackground)
}, (0, _fEngine.jsx)("text", {
style: (0, _tslib.__assign)((0, _tslib.__assign)({}, xTipTextStyle), {
text: xPositionType === 'coord' ? coordData.xText : (0, _util.isFunction)(xTip) ? xTip(xFirstText, firstRecord) : xFirstText
})
}));
};
var RenderYTip = function RenderYTip(props) {
var records = props.records,
coord = props.coord,
yTip = props.yTip,
yPositionType = props.yPositionType,
yTipTextStyle = props.yTipTextStyle,
yTipBackground = props.yTipBackground;
var coordLeft = coord.left;
var firstRecord = records[0];
var y = firstRecord.y,
coordData = firstRecord.coord;
var yFirstText = firstRecord.value;
return (0, _fEngine.jsx)("rect", {
style: (0, _tslib.__assign)({
display: 'flex',
left: coordLeft,
top: yPositionType === 'coord' ? coordData.y : y
}, yTipBackground)
}, (0, _fEngine.jsx)("text", {
style: (0, _tslib.__assign)((0, _tslib.__assign)({}, yTipTextStyle), {
text: yPositionType === 'coord' ? coordData.yText : (0, _util.isFunction)(yTip) ? yTip(yFirstText, firstRecord) : yFirstText
})
}));
};
// tooltip 内容框
var RenderLabel = /** @class */function (_super) {
(0, _tslib.__extends)(RenderLabel, _super);
function RenderLabel() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.style = {};
return _this;
}
RenderLabel.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
};
};
RenderLabel.prototype._getContainerLayout = function () {
var _a = this.props,
records = _a.records,
coord = _a.coord;
if (!records || !records.length) return;
var width = coord.width;
var node = (0, _fEngine.computeLayout)(this, this.render());
var itemMaxWidth = this.getMaxItemBox(node === null || node === void 0 ? void 0 : node.children[0]).width;
// 每行最多的个数
var lineMaxCount = Math.max(1, Math.floor(width / itemMaxWidth));
var itemCount = records.length;
// 是否需要换行
if (itemCount > lineMaxCount) {
this.style = {
width: width
};
}
};
RenderLabel.prototype.willMount = function () {
this._getContainerLayout();
};
RenderLabel.prototype.render = function () {
var _this = this;
var _a = this.props,
records = _a.records,
background = _a.background,
showItemMarker = _a.showItemMarker,
itemMarkerStyle = _a.itemMarkerStyle,
customText = _a.customText,
nameStyle = _a.nameStyle,
valueStyle = _a.valueStyle,
joinString = _a.joinString,
arrowWidth = _a.arrowWidth,
x = _a.x,
coord = _a.coord,
itemWidth = _a.itemWidth;
// 显示内容
var labelView = function labelView(left, top) {
return (0, _fEngine.jsx)("group", {
style: {
display: 'flex'
}
}, (0, _fEngine.jsx)("group", {
style: (0, _tslib.__assign)((0, _tslib.__assign)({
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
padding: [0, 0, 0, '6px'],
left: left,
top: top
}, _this.style), background)
}, records.map(function (record) {
var name = record.name,
value = record.value;
return (0, _fEngine.jsx)("group", {
style: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
padding: [0, '6px', 0, 0],
width: itemWidth
}
}, showItemMarker ? (0, _fEngine.jsx)("marker", {
style: (0, _tslib.__assign)((0, _tslib.__assign)({
width: itemMarkerStyle.width,
marginRight: '6px'
}, itemMarkerStyle), {
fill: record.color
})
}) : null, customText && (0, _util.isFunction)(customText) ? customText(record) : (0, _fEngine.jsx)("group", {
style: {
display: 'flex',
flexDirection: 'row'
}
}, (0, _fEngine.jsx)("text", {
style: (0, _tslib.__assign)((0, _tslib.__assign)({}, nameStyle), {
text: value ? "".concat(name).concat(joinString) : name
})
}), (0, _fEngine.jsx)("text", {
style: (0, _tslib.__assign)((0, _tslib.__assign)({}, valueStyle), {
text: value
})
})));
})), (0, _fEngine.jsx)("group", null, (0, _fEngine.jsx)("polygon", {
style: {
points: [[x - arrowWidth, top], [x + arrowWidth, top], [x, top + arrowWidth]],
fill: background.fill
}
})));
};
// 计算显示位置
var layout = (0, _fEngine.computeLayout)(this, labelView(0, 0)).layout; // 获取内容区大小
var coordLeft = coord.left,
coordTop = coord.top,
coordRight = coord.right;
var width = layout.width,
height = layout.height;
var halfWidth = width / 2;
// 让 tooltip 限制在 coord 的显示范围内
var advanceLeft = x - halfWidth;
var advanceTop = coordTop - height;
var left = advanceLeft < coordLeft ? coordLeft : advanceLeft > coordRight - width ? coordRight - width : advanceLeft;
var top = advanceTop < 0 ? 0 : advanceTop;
return labelView(left, top);
};
return RenderLabel;
}(_fEngine.Component);
var TooltipView = /** @class */function (_super) {
(0, _tslib.__extends)(TooltipView, _super);
function TooltipView() {
return _super !== null && _super.apply(this, arguments) || this;
}
TooltipView.prototype.render = function () {
var _a = this,
props = _a.props,
context = _a.context;
var records = props.records,
coord = props.coord;
var firstRecord = records[0];
var x = firstRecord.x,
coordData = firstRecord.coord;
var chart = props.chart,
customBackground = props.background,
_b = props.showTooltipMarker,
showTooltipMarker = _b === void 0 ? defaultStyle.showTooltipMarker : _b,
_c = props.markerBackgroundStyle,
markerBackgroundStyle = _c === void 0 ? defaultStyle.markerBackgroundStyle : _c,
_d = props.showItemMarker,
showItemMarker = _d === void 0 ? defaultStyle.showItemMarker : _d,
customItemMarkerStyle = props.itemMarkerStyle,
nameStyle = props.nameStyle,
valueStyle = props.valueStyle,
_e = props.joinString,
joinString = _e === void 0 ? defaultStyle.joinString : _e,
_f = props.showCrosshairs,
showCrosshairs = _f === void 0 ? defaultStyle.showCrosshairs : _f,
crosshairsStyle = props.crosshairsStyle,
_g = props.crosshairsType,
crosshairsType = _g === void 0 ? defaultStyle.crosshairsType : _g,
_h = props.snap,
snap = _h === void 0 ? defaultStyle.snap : _h,
_j = props.tooltipMarkerStyle,
tooltipMarkerStyle = _j === void 0 ? defaultStyle.tooltipMarkerStyle : _j,
showXTip = props.showXTip,
xPositionType = props.xPositionType,
showYTip = props.showYTip,
yPositionType = props.yPositionType,
xTip = props.xTip,
yTip = props.yTip,
_k = props.xTipTextStyle,
xTipTextStyle = _k === void 0 ? defaultStyle.xTipTextStyle : _k,
_l = props.yTipTextStyle,
yTipTextStyle = _l === void 0 ? defaultStyle.yTipTextStyle : _l,
_m = props.xTipBackground,
xTipBackground = _m === void 0 ? defaultStyle.xTipBackground : _m,
_o = props.yTipBackground,
yTipBackground = _o === void 0 ? defaultStyle.yTipBackground : _o,
_p = props.custom,
custom = _p === void 0 ? false : _p,
customText = props.customText,
itemWidth = props.itemWidth;
var itemMarkerStyle = (0, _tslib.__assign)((0, _tslib.__assign)({}, customItemMarkerStyle), defaultStyle.itemMarkerStyle);
var background = (0, _tslib.__assign)((0, _tslib.__assign)({}, defaultStyle.background), customBackground);
var arrowWidth = context.px2hd('6px');
return (0, _fEngine.jsx)("group", null, showTooltipMarker ? (0, _fEngine.jsx)(RenderItemMarker, {
coord: coord,
context: context,
records: records,
markerBackgroundStyle: markerBackgroundStyle
}) : null, showCrosshairs ? (0, _fEngine.jsx)(RenderCrosshairs, {
chart: chart,
coord: coord,
records: records,
xPositionType: xPositionType,
yPositionType: yPositionType,
crosshairsType: crosshairsType,
crosshairsStyle: (0, _tslib.__assign)((0, _tslib.__assign)({}, defaultStyle.crosshairsStyle), crosshairsStyle)
}) : null, snap ? records.map(function (item) {
var x = item.x,
y = item.y,
color = item.color,
shape = item.shape;
return (0, _fEngine.jsx)("circle", {
style: (0, _tslib.__assign)((0, _tslib.__assign)({
cx: xPositionType === 'coord' ? coordData.x : x,
cy: yPositionType === 'coord' ? coordData.y : y,
r: '6px',
stroke: color,
fill: color
}, shape), tooltipMarkerStyle)
});
}) : null, showXTip && (0, _fEngine.jsx)(RenderXTip, {
records: records,
coord: coord,
xTip: xTip,
xPositionType: xPositionType,
xTipTextStyle: (0, _tslib.__assign)((0, _tslib.__assign)({}, defaultStyle.xTipTextStyle), xTipTextStyle),
xTipBackground: (0, _tslib.__assign)((0, _tslib.__assign)({}, defaultStyle.xTipBackground), xTipBackground)
}), showYTip && (0, _fEngine.jsx)(RenderYTip, {
records: records,
coord: coord,
yTip: yTip,
yPositionType: yPositionType,
yTipTextStyle: (0, _tslib.__assign)((0, _tslib.__assign)({}, defaultStyle.yTipTextStyle), yTipTextStyle),
yTipBackground: (0, _tslib.__assign)((0, _tslib.__assign)({}, defaultStyle.yTipBackground), yTipBackground)
}), !custom && (0, _fEngine.jsx)(RenderLabel, {
records: records,
coord: coord,
itemMarkerStyle: itemMarkerStyle,
customText: customText,
showItemMarker: showItemMarker,
x: x,
arrowWidth: arrowWidth,
background: background,
nameStyle: (0, _tslib.__assign)((0, _tslib.__assign)({}, defaultStyle.nameStyle), nameStyle),
valueStyle: (0, _tslib.__assign)((0, _tslib.__assign)({}, defaultStyle.valueStyle), valueStyle),
joinString: joinString,
itemWidth: itemWidth
}));
};
return TooltipView;
}(_fEngine.Component);
var _default = exports.default = TooltipView;