刻度定位
在图表的类别轴上找到一个给定刻度值 (targetTickId) 的位置 (coord)
coord:Number;=>像素值 为空间位置
targetValue:Number;=> 刻度线某处所代表的值
遍历刻度线
- 如果 tickValue 等于 targetTickId,则找到了目标位置,赋值给 coord 并退出循环。
- 如果 tickValue 小于 targetTickId,更新 leftCoord 为当前遍历处刻度的位置。
- 如果 tickValue 大于 targetTickId,并且 leftCoord 已经有值,说明 targetTickId 在 leftCoord 和当前刻度之间。计算它们的中间位置作为 coord 并退出循环。
getMarkerPosition(
value: ScaleDataValue[],
dims?: typeof dimPermutations[number],
startingAtTick?: boolean
) {
const coordSys = this.coordinateSystem;
if (coordSys && coordSys.clampData) {
// PENDING if clamp ?
const clampData = coordSys.clampData(value);
const pt = coordSys.dataToPoint(clampData);
if (startingAtTick) {
each(coordSys.getAxes(), function (axis: Axis2D, idx: number) {
// If axis type is category, use tick coords instead
if (axis.type === 'category' && dims != null) {
const tickCoords = axis.getTicksCoords();
const alignTicksWithLabel = axis.getTickModel().get('alignWithLabel');
//targetTickValue 作为变量名比 targetTickId 更能准确地表达其含义
let targetTickId = clampData[idx];
// The index of rightmost tick of markArea is 1 larger than x1/y1 index
const isEnd = dims[idx] === 'x1' || dims[idx] === 'y1';
if (isEnd && !alignTicksWithLabel) {
targetTickId += 1;
}
// The only contains one tick, tickCoords is
// like [{coord: 0, tickValue: 0}, {coord: 0}]
// to the length should always be larger than 1
if (tickCoords.length < 2) {
return;
}
else if (tickCoords.length === 2) {
// The left value and right value of the axis are
// the same. coord is 0 in both items. Use the max
// value of the axis as the coord
pt[idx] = axis.toGlobalCoord(
axis.getExtent()[isEnd ? 1 : 0]
);
return;
}
let leftCoord;
let coord;
let stepTickValue = 1;
for (let i = 0; i < tickCoords.length; i++) {
const tickCoord = tickCoords[i].coord;
// The last item of tickCoords doesn't contain
// tickValue
const tickValue = i === tickCoords.length - 1
? tickCoords[i - 1].tickValue + stepTickValue
//对于最后一个刻度(i === tickCoords.length - 1),由于它通常表示轴的边界,
//所以我们用前一个刻度的 tickValue 加上步长 (stepTickValue) 来模拟最后一个刻度的值。
: tickCoords[i].tickValue;
if (tickValue === targetTickId) {
coord = tickCoord;
break;
}
else if (tickValue < targetTickId) {
leftCoord = tickCoord;
}
else if (leftCoord != null && tickValue > targetTickId) {
coord = (tickCoord + leftCoord) / 2;
break;
}
if (i === 1) {
// Here we assume the step of category axes is
// the same
stepTickValue = tickValue - tickCoords[0].tickValue;
}
}
if (coord == null) {
if (!leftCoord) {
// targetTickId is smaller than all tick ids in the
// visible area, use the leftmost tick coord
coord = tickCoords[0].coord;
}
else if (leftCoord) {
// targetTickId is larger than all tick ids in the
// visible area, use the rightmost tick coord
coord = tickCoords[tickCoords.length - 1].coord;
}
}
pt[idx] = axis.toGlobalCoord(coord);
}
});
}
else {
const data = this.getData();
const offset = data.getLayout('offset');
const size = data.getLayout('size');
const offsetIndex = (coordSys as Cartesian2D).getBaseAxis().isHorizontal() ? 0 : 1;
pt[offsetIndex] += offset + size / 2;
}
return pt;
}
return [NaN, NaN];
}