-
Notifications
You must be signed in to change notification settings - Fork 217
Expand file tree
/
Copy pathcommon.ts
More file actions
134 lines (118 loc) · 4.16 KB
/
Copy pathcommon.ts
File metadata and controls
134 lines (118 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import type { Tag } from '@visactor/vrender-components';
import type { IBoundsLike } from '@visactor/vutils';
import type { Datum } from '../../../typings';
import type { ICrosshairTheme } from '../interface';
// eslint-disable-next-line no-duplicate-imports
import { array, isValid } from '@visactor/vutils';
import { isXAxis, isYAxis } from '../../axis/cartesian/util/common';
import { isDiscrete } from '@visactor/vscale';
import type { ICartesianAxisCommonSpec, IPolarAxisCommonSpec } from '../../axis';
import { getComponentThemeFromOption } from '../../util';
import { ComponentTypeEnum } from '../../interface/type';
import { isDiscreteAxis } from '../../axis/util';
import { mergeSpec } from '@visactor/vutils-extension';
export function limitTagInBounds(shape: Tag, bounds: IBoundsLike) {
const { x1: regionMinX, y1: regionMinY, x2: regionMaxX, y2: regionMaxY } = bounds;
const { x1, y1, x2, y2 } = shape.AABBBounds;
const { dx: originDx = 0, dy: originDy = 0 } = shape.attribute;
let dx = 0;
let dy = 0;
if (x1 < regionMinX) {
// 超出左侧
dx = regionMinX - x1;
}
if (y1 < regionMinY) {
// 超出顶部
dy = regionMinY - y1;
}
if (x2 > regionMaxX) {
// 超出右侧
dx = regionMaxX - x2;
}
if (y2 > regionMaxY) {
// 整体超出顶部
dy = regionMaxY - y2;
}
if (dx) {
shape.setAttribute('dx', dx + originDx);
}
if (dy) {
shape.setAttribute('dy', dy + originDy);
}
}
/**
* 查找系列中的数据
* @todo 待重构优化,和 `getDimensionData` 中的逻辑存在重合
* @param data 系列数据
* @param value 数据值
* @param startField 开始值对应的字段
* @param endField 结束值对应的字段
* @returns 系列数据
*/
export function getDatumByValue(data: Datum[], value: number, startField: string, endField?: string): Datum | null {
for (let i = 0, len = data.length; i < len; i++) {
const record = data[i];
if (record) {
const startValue = record[startField];
const endValue = record[endField || startField];
const min = Math.min(startValue, endValue);
const max = Math.max(startValue, endValue);
if (min <= value && max >= value) {
return record;
}
}
}
return null;
}
export const getCartesianCrosshairTheme = (getTheme: (...keys: string[]) => any, chartSpec: any): ICrosshairTheme => {
const axes: ICartesianAxisCommonSpec[] = array(chartSpec.axes ?? []);
const { bandField, linearField, xField, yField, trigger, triggerOff } =
getComponentThemeFromOption(ComponentTypeEnum.crosshair, getTheme) ?? {};
const xAxis = axes.find(axis => isXAxis(axis.orient));
let newXField;
if (isValid(xAxis)) {
newXField = mergeSpec({}, isDiscreteAxis(xAxis.type) ? bandField : linearField, xField);
} else {
newXField = xField;
}
const yAxis = axes.find(axis => isYAxis(axis.orient));
let newYField;
if (isValid(yAxis)) {
newYField = mergeSpec({}, isDiscrete(yAxis.type) ? bandField : linearField, yField);
} else {
newYField = yField;
}
// 返回主题配置,包括交互相关配置
return {
xField: newXField,
yField: newYField,
trigger,
triggerOff
};
};
export const getPolarCrosshairTheme = (getTheme: (...keys: string[]) => any, chartSpec: any): ICrosshairTheme => {
const axes: IPolarAxisCommonSpec[] = array(chartSpec.axes ?? []);
const { bandField, linearField, categoryField, valueField, trigger, triggerOff } =
getComponentThemeFromOption(ComponentTypeEnum.crosshair, getTheme) ?? {};
const angleAxis = axes.find(axis => axis.orient === 'angle');
let newAngleField;
if (isValid(angleAxis)) {
newAngleField = mergeSpec({}, isDiscreteAxis(angleAxis.type) ? bandField : linearField, categoryField);
} else {
newAngleField = categoryField;
}
const radiusAxis = axes.find(axis => axis.orient === 'radius');
let newRadiusField;
if (isValid(radiusAxis)) {
newRadiusField = mergeSpec({}, isDiscrete(radiusAxis.type) ? bandField : linearField, valueField);
} else {
newRadiusField = valueField;
}
// 返回主题配置,包括交互相关配置
return {
categoryField: newAngleField,
valueField: newRadiusField,
trigger,
triggerOff
};
};