UNPKG

15.4 kBJavaScriptView Raw
1import { __assign, __extends, __spreadArray } from "tslib";
2import { Component, jsx, computeLayout } from '@antv/f-engine';
3import { isFunction, find } from '@antv/util';
4// view 的默认配置
5var defaultStyle = {
6 showTitle: false,
7 showCrosshairs: false,
8 crosshairsType: 'y',
9 crosshairsStyle: {
10 stroke: 'rgba(0, 0, 0, 0.25)',
11 lineWidth: '2px'
12 },
13 showTooltipMarker: false,
14 markerBackgroundStyle: {
15 fill: '#CCD6EC',
16 opacity: 0.3,
17 padding: '6px'
18 },
19 tooltipMarkerStyle: {
20 fill: '#fff',
21 lineWidth: '3px'
22 },
23 background: {
24 radius: '4px',
25 fill: 'rgba(0, 0, 0, 0.65)',
26 padding: ['6px', '10px']
27 },
28 titleStyle: {
29 fontSize: '24px',
30 fill: '#fff',
31 textAlign: 'start',
32 textBaseline: 'top'
33 },
34 nameStyle: {
35 fontSize: '24px',
36 fill: 'rgba(255, 255, 255, 0.65)',
37 textAlign: 'start',
38 textBaseline: 'middle'
39 },
40 valueStyle: {
41 fontSize: '24px',
42 fill: '#fff',
43 textAlign: 'start',
44 textBaseline: 'middle'
45 },
46 joinString: ': ',
47 showItemMarker: true,
48 itemMarkerStyle: {
49 width: '12px',
50 radius: '6px',
51 symbol: 'circle',
52 lineWidth: '2px',
53 stroke: '#fff'
54 },
55 layout: 'horizontal',
56 snap: false,
57 xTipTextStyle: {
58 fontSize: '24px',
59 fill: '#fff'
60 },
61 yTipTextStyle: {
62 fontSize: '24px',
63 fill: '#fff'
64 },
65 xTipBackground: {
66 radius: '4px',
67 fill: 'rgba(0, 0, 0, 0.65)',
68 padding: ['6px', '10px'],
69 marginLeft: '-50%',
70 marginTop: '6px'
71 },
72 yTipBackground: {
73 radius: '4px',
74 fill: 'rgba(0, 0, 0, 0.65)',
75 padding: ['6px', '10px'],
76 marginLeft: '-100%',
77 marginTop: '-50%'
78 }
79};
80function directionEnabled(mode, dir) {
81 if (mode === undefined) {
82 return true;
83 } else if (typeof mode === 'string') {
84 return mode.indexOf(dir) !== -1;
85 }
86 return false;
87}
88var RenderItemMarker = function RenderItemMarker(props) {
89 var records = props.records,
90 coord = props.coord,
91 context = props.context,
92 markerBackgroundStyle = props.markerBackgroundStyle;
93 var point = coord.convertPoint({
94 x: 1,
95 y: 1
96 });
97 var padding = context.px2hd(markerBackgroundStyle.padding || '6px');
98 var xPoints = __spreadArray(__spreadArray([], records.map(function (record) {
99 return record.xMin;
100 }), true), records.map(function (record) {
101 return record.xMax;
102 }), true);
103 var yPoints = __spreadArray(__spreadArray([], records.map(function (record) {
104 return record.yMin;
105 }), true), records.map(function (record) {
106 return record.yMax;
107 }), true);
108 if (coord.transposed) {
109 xPoints.push(point.x);
110 } else {
111 yPoints.push(point.y);
112 }
113 var xMin = Math.min.apply(null, xPoints);
114 var xMax = Math.max.apply(null, xPoints);
115 var yMin = Math.min.apply(null, yPoints);
116 var yMax = Math.max.apply(null, yPoints);
117 var x = coord.transposed ? xMin : xMin - padding;
118 var y = coord.transposed ? yMin - padding : yMin;
119 var width = coord.transposed ? xMax - xMin : xMax - xMin + 2 * padding;
120 var height = coord.transposed ? yMax - yMin + 2 * padding : yMax - yMin;
121 return jsx("rect", {
122 style: __assign({
123 x: x,
124 y: y,
125 width: width,
126 height: height
127 }, markerBackgroundStyle)
128 });
129};
130var RenderCrosshairs = function RenderCrosshairs(props) {
131 var records = props.records,
132 coord = props.coord,
133 chart = props.chart,
134 crosshairsType = props.crosshairsType,
135 crosshairsStyle = props.crosshairsStyle,
136 xPositionType = props.xPositionType,
137 yPositionType = props.yPositionType;
138 var coordLeft = coord.left,
139 coordTop = coord.top,
140 coordRight = coord.right,
141 coordBottom = coord.bottom,
142 center = coord.center;
143 var firstRecord = records[0];
144 var x = firstRecord.x,
145 y = firstRecord.y,
146 origin = firstRecord.origin,
147 xField = firstRecord.xField,
148 coordData = firstRecord.coord;
149 if (coord.isPolar) {
150 // 极坐标下的辅助线
151 var xScale = chart.getScale(xField);
152 var ticks = xScale.getTicks();
153 var tick = find(ticks, function (tick) {
154 return origin[xField] === tick.tickValue;
155 });
156 var end = coord.convertPoint({
157 x: tick.value,
158 y: 1
159 });
160 return jsx("line", {
161 style: __assign({
162 x1: center.x,
163 y1: center.y,
164 x2: end.x,
165 y2: end.y
166 }, crosshairsStyle)
167 });
168 }
169 return jsx("group", null, directionEnabled(crosshairsType, 'x') ? jsx("line", {
170 style: __assign({
171 x1: coordLeft,
172 y1: yPositionType === 'coord' ? coordData.y : y,
173 x2: coordRight,
174 y2: yPositionType === 'coord' ? coordData.y : y
175 }, crosshairsStyle)
176 }) : null, directionEnabled(crosshairsType, 'y') ? jsx("line", {
177 style: __assign({
178 x1: xPositionType === 'coord' ? coordData.x : x,
179 y1: coordTop,
180 x2: xPositionType === 'coord' ? coordData.x : x,
181 y2: coordBottom
182 }, crosshairsStyle)
183 }) : null);
184};
185var RenderXTip = function RenderXTip(props) {
186 var records = props.records,
187 coord = props.coord,
188 xTip = props.xTip,
189 xPositionType = props.xPositionType,
190 xTipTextStyle = props.xTipTextStyle,
191 xTipBackground = props.xTipBackground;
192 var coordBottom = coord.bottom;
193 var firstRecord = records[0];
194 var x = firstRecord.x,
195 coordData = firstRecord.coord;
196 var xFirstText = firstRecord.name;
197 return jsx("rect", {
198 style: __assign({
199 display: 'flex',
200 left: xPositionType === 'coord' ? coordData.x : x,
201 top: coordBottom
202 }, xTipBackground)
203 }, jsx("text", {
204 style: __assign(__assign({}, xTipTextStyle), {
205 text: xPositionType === 'coord' ? coordData.xText : isFunction(xTip) ? xTip(xFirstText, firstRecord) : xFirstText
206 })
207 }));
208};
209var RenderYTip = function RenderYTip(props) {
210 var records = props.records,
211 coord = props.coord,
212 yTip = props.yTip,
213 yPositionType = props.yPositionType,
214 yTipTextStyle = props.yTipTextStyle,
215 yTipBackground = props.yTipBackground;
216 var coordLeft = coord.left;
217 var firstRecord = records[0];
218 var y = firstRecord.y,
219 coordData = firstRecord.coord;
220 var yFirstText = firstRecord.value;
221 return jsx("rect", {
222 style: __assign({
223 display: 'flex',
224 left: coordLeft,
225 top: yPositionType === 'coord' ? coordData.y : y
226 }, yTipBackground)
227 }, jsx("text", {
228 style: __assign(__assign({}, yTipTextStyle), {
229 text: yPositionType === 'coord' ? coordData.yText : isFunction(yTip) ? yTip(yFirstText, firstRecord) : yFirstText
230 })
231 }));
232};
233// tooltip 内容框
234var RenderLabel = /** @class */function (_super) {
235 __extends(RenderLabel, _super);
236 function RenderLabel() {
237 var _this = _super !== null && _super.apply(this, arguments) || this;
238 _this.style = {};
239 return _this;
240 }
241 RenderLabel.prototype.getMaxItemBox = function (node) {
242 var maxItemWidth = 0;
243 var maxItemHeight = 0;
244 (node.children || []).forEach(function (child) {
245 var layout = child.layout;
246 var width = layout.width,
247 height = layout.height;
248 maxItemWidth = Math.max(maxItemWidth, width);
249 maxItemHeight = Math.max(maxItemHeight, height);
250 });
251 return {
252 width: maxItemWidth,
253 height: maxItemHeight
254 };
255 };
256 RenderLabel.prototype._getContainerLayout = function () {
257 var _a = this.props,
258 records = _a.records,
259 coord = _a.coord;
260 if (!records || !records.length) return;
261 var width = coord.width;
262 var node = computeLayout(this, this.render());
263 var itemMaxWidth = this.getMaxItemBox(node === null || node === void 0 ? void 0 : node.children[0]).width;
264 // 每行最多的个数
265 var lineMaxCount = Math.max(1, Math.floor(width / itemMaxWidth));
266 var itemCount = records.length;
267 // 是否需要换行
268 if (itemCount > lineMaxCount) {
269 this.style = {
270 width: width
271 };
272 }
273 };
274 RenderLabel.prototype.willMount = function () {
275 this._getContainerLayout();
276 };
277 RenderLabel.prototype.render = function () {
278 var _this = this;
279 var _a = this.props,
280 records = _a.records,
281 background = _a.background,
282 showItemMarker = _a.showItemMarker,
283 itemMarkerStyle = _a.itemMarkerStyle,
284 customText = _a.customText,
285 nameStyle = _a.nameStyle,
286 valueStyle = _a.valueStyle,
287 joinString = _a.joinString,
288 arrowWidth = _a.arrowWidth,
289 x = _a.x,
290 coord = _a.coord,
291 itemWidth = _a.itemWidth;
292 // 显示内容
293 var labelView = function labelView(left, top) {
294 return jsx("group", {
295 style: {
296 display: 'flex'
297 }
298 }, jsx("group", {
299 style: __assign(__assign({
300 display: 'flex',
301 flexDirection: 'row',
302 flexWrap: 'wrap',
303 padding: [0, 0, 0, '6px'],
304 left: left,
305 top: top
306 }, _this.style), background)
307 }, records.map(function (record) {
308 var name = record.name,
309 value = record.value;
310 return jsx("group", {
311 style: {
312 display: 'flex',
313 flexDirection: 'row',
314 alignItems: 'center',
315 padding: [0, '6px', 0, 0],
316 width: itemWidth
317 }
318 }, showItemMarker ? jsx("marker", {
319 style: __assign(__assign({
320 width: itemMarkerStyle.width,
321 marginRight: '6px'
322 }, itemMarkerStyle), {
323 fill: record.color
324 })
325 }) : null, customText && isFunction(customText) ? customText(record) : jsx("group", {
326 style: {
327 display: 'flex',
328 flexDirection: 'row'
329 }
330 }, jsx("text", {
331 style: __assign(__assign({}, nameStyle), {
332 text: value ? "".concat(name).concat(joinString) : name
333 })
334 }), jsx("text", {
335 style: __assign(__assign({}, valueStyle), {
336 text: value
337 })
338 })));
339 })), jsx("group", null, jsx("polygon", {
340 style: {
341 points: [[x - arrowWidth, top], [x + arrowWidth, top], [x, top + arrowWidth]],
342 fill: background.fill
343 }
344 })));
345 };
346 // 计算显示位置
347 var layout = computeLayout(this, labelView(0, 0)).layout; // 获取内容区大小
348 var coordLeft = coord.left,
349 coordTop = coord.top,
350 coordRight = coord.right;
351 var width = layout.width,
352 height = layout.height;
353 var halfWidth = width / 2;
354 // 让 tooltip 限制在 coord 的显示范围内
355 var advanceLeft = x - halfWidth;
356 var advanceTop = coordTop - height;
357 var left = advanceLeft < coordLeft ? coordLeft : advanceLeft > coordRight - width ? coordRight - width : advanceLeft;
358 var top = advanceTop < 0 ? 0 : advanceTop;
359 return labelView(left, top);
360 };
361 return RenderLabel;
362}(Component);
363var TooltipView = /** @class */function (_super) {
364 __extends(TooltipView, _super);
365 function TooltipView() {
366 return _super !== null && _super.apply(this, arguments) || this;
367 }
368 TooltipView.prototype.render = function () {
369 var _a = this,
370 props = _a.props,
371 context = _a.context;
372 var records = props.records,
373 coord = props.coord;
374 var firstRecord = records[0];
375 var x = firstRecord.x,
376 coordData = firstRecord.coord;
377 var chart = props.chart,
378 customBackground = props.background,
379 _b = props.showTooltipMarker,
380 showTooltipMarker = _b === void 0 ? defaultStyle.showTooltipMarker : _b,
381 _c = props.markerBackgroundStyle,
382 markerBackgroundStyle = _c === void 0 ? defaultStyle.markerBackgroundStyle : _c,
383 _d = props.showItemMarker,
384 showItemMarker = _d === void 0 ? defaultStyle.showItemMarker : _d,
385 customItemMarkerStyle = props.itemMarkerStyle,
386 nameStyle = props.nameStyle,
387 valueStyle = props.valueStyle,
388 _e = props.joinString,
389 joinString = _e === void 0 ? defaultStyle.joinString : _e,
390 _f = props.showCrosshairs,
391 showCrosshairs = _f === void 0 ? defaultStyle.showCrosshairs : _f,
392 crosshairsStyle = props.crosshairsStyle,
393 _g = props.crosshairsType,
394 crosshairsType = _g === void 0 ? defaultStyle.crosshairsType : _g,
395 _h = props.snap,
396 snap = _h === void 0 ? defaultStyle.snap : _h,
397 _j = props.tooltipMarkerStyle,
398 tooltipMarkerStyle = _j === void 0 ? defaultStyle.tooltipMarkerStyle : _j,
399 showXTip = props.showXTip,
400 xPositionType = props.xPositionType,
401 showYTip = props.showYTip,
402 yPositionType = props.yPositionType,
403 xTip = props.xTip,
404 yTip = props.yTip,
405 _k = props.xTipTextStyle,
406 xTipTextStyle = _k === void 0 ? defaultStyle.xTipTextStyle : _k,
407 _l = props.yTipTextStyle,
408 yTipTextStyle = _l === void 0 ? defaultStyle.yTipTextStyle : _l,
409 _m = props.xTipBackground,
410 xTipBackground = _m === void 0 ? defaultStyle.xTipBackground : _m,
411 _o = props.yTipBackground,
412 yTipBackground = _o === void 0 ? defaultStyle.yTipBackground : _o,
413 _p = props.custom,
414 custom = _p === void 0 ? false : _p,
415 customText = props.customText,
416 itemWidth = props.itemWidth;
417 var itemMarkerStyle = __assign(__assign({}, customItemMarkerStyle), defaultStyle.itemMarkerStyle);
418 var background = __assign(__assign({}, defaultStyle.background), customBackground);
419 var arrowWidth = context.px2hd('6px');
420 return jsx("group", null, showTooltipMarker ? jsx(RenderItemMarker, {
421 coord: coord,
422 context: context,
423 records: records,
424 markerBackgroundStyle: markerBackgroundStyle
425 }) : null, showCrosshairs ? jsx(RenderCrosshairs, {
426 chart: chart,
427 coord: coord,
428 records: records,
429 xPositionType: xPositionType,
430 yPositionType: yPositionType,
431 crosshairsType: crosshairsType,
432 crosshairsStyle: __assign(__assign({}, defaultStyle.crosshairsStyle), crosshairsStyle)
433 }) : null, snap ? records.map(function (item) {
434 var x = item.x,
435 y = item.y,
436 color = item.color,
437 shape = item.shape;
438 return jsx("circle", {
439 style: __assign(__assign({
440 cx: xPositionType === 'coord' ? coordData.x : x,
441 cy: yPositionType === 'coord' ? coordData.y : y,
442 r: '6px',
443 stroke: color,
444 fill: color
445 }, shape), tooltipMarkerStyle)
446 });
447 }) : null, showXTip && jsx(RenderXTip, {
448 records: records,
449 coord: coord,
450 xTip: xTip,
451 xPositionType: xPositionType,
452 xTipTextStyle: __assign(__assign({}, defaultStyle.xTipTextStyle), xTipTextStyle),
453 xTipBackground: __assign(__assign({}, defaultStyle.xTipBackground), xTipBackground)
454 }), showYTip && jsx(RenderYTip, {
455 records: records,
456 coord: coord,
457 yTip: yTip,
458 yPositionType: yPositionType,
459 yTipTextStyle: __assign(__assign({}, defaultStyle.yTipTextStyle), yTipTextStyle),
460 yTipBackground: __assign(__assign({}, defaultStyle.yTipBackground), yTipBackground)
461 }), !custom && jsx(RenderLabel, {
462 records: records,
463 coord: coord,
464 itemMarkerStyle: itemMarkerStyle,
465 customText: customText,
466 showItemMarker: showItemMarker,
467 x: x,
468 arrowWidth: arrowWidth,
469 background: background,
470 nameStyle: __assign(__assign({}, defaultStyle.nameStyle), nameStyle),
471 valueStyle: __assign(__assign({}, defaultStyle.valueStyle), valueStyle),
472 joinString: joinString,
473 itemWidth: itemWidth
474 }));
475 };
476 return TooltipView;
477}(Component);
478export default TooltipView;
\No newline at end of file