Skip to content

Commit

Permalink
fix: swipe 支撑单向快扫 (#1891)
Browse files Browse the repository at this point in the history
  • Loading branch information
zengyue committed Nov 23, 2023
1 parent 58c6d95 commit 95a2c50
Show file tree
Hide file tree
Showing 8 changed files with 405 additions and 7 deletions.
5 changes: 5 additions & 0 deletions packages/f2/src/components/zoom/easing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function quadraticOut(k) {
return k * (2 - k);
}

export { quadraticOut };
99 changes: 95 additions & 4 deletions packages/f2/src/components/zoom/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ChartChildProps } from '../../chart';
import { updateRange, updateFollow } from './zoomUtil';
import { Scale, ScaleConfig } from '../../deps/f2-scale/src';
import { each, isNumberEqual, isArray } from '@antv/util';
import { quadraticOut as easeing } from './easing';

export type ZoomRange = [number, number];
export type ScaleValues = number[] | string[];
Expand Down Expand Up @@ -52,6 +53,10 @@ export interface ZoomProps {
* 横扫
*/
swipe?: boolean;
/**
* 横扫动画时长
*/
swipeDuration?: number;
/**
* 事件回调
*/
Expand Down Expand Up @@ -174,6 +179,40 @@ export default (View) => {
} as S;
}

willUpdate(): void {
const { props, state, dims } = this;
const { minCount, range } = props;
let valueLength = Number.MIN_VALUE;
const cacheRange = {};

each(dims, (dim) => {
const scale = this._getScale(dim);
// scale 没有变化, 不处理
if (scale === this.scale[dim]) {
return;
}
const { values } = scale;
valueLength = values.length > valueLength ? values.length : valueLength;
this.scale[dim] = scale;
this.originScale[dim] = cloneScale(scale);
// 让 range 触发更新
this.state.range[dim] = [0, 1];
this.updateRange(range, dim);
cacheRange[dim] = range;
});

// 有变化
if (Object.keys(cacheRange).length > 0) {
this.minScale = minCount / valueLength;
const newRange = {
...state.range,
...cacheRange,
};

this.renderRange(newRange);
}
}

didUnmount(): void {
this.loop && cancelAnimationFrame(this.loop);
}
Expand Down Expand Up @@ -284,12 +323,64 @@ export default (View) => {
}
}

animateSwipe(dim: string, dimRange: ZoomRange, velocity: number) {
const { context, props } = this;
const { requestAnimationFrame } = context.canvas;
const { swipeDuration = 1000 } = props;

const diff = (dimRange[1] - dimRange[0]) * velocity;

const startTime = Date.now();

const updateRange = (t: number) => {
const newDimRange: ZoomRange = [dimRange[0] + diff * t, dimRange[1] + diff * t];
const newRange = this.updateRange(newDimRange, dim);
this.renderRange({
x: newRange,
});
};

// 更新动画
const update = () => {
// 计算动画已经进行的时间
const currentTime = Date.now() - startTime;

// 如果动画已经结束,则清除定时器
if (currentTime >= swipeDuration) {
updateRange(1);
return;
}

// 计算缓动值
const progress = currentTime / swipeDuration;
const easedProgress = easeing(progress);
updateRange(easedProgress);

requestAnimationFrame(() => {
update();
});
};
update();
}

onSwipe = (ev) => {
const { swipe } = this.props;
if (this.props.mode.length < 2 || !swipe) return;
const { props, state } = this;
// 滑动速率
const { velocity, direction, velocityX = 0, velocityY = 0, points } = ev;
const { mode, swipe } = props;
const { range } = state;

const { velocityX = 0, velocityY = 0, points } = ev;
const { range } = this.state;
if (!swipe || !mode) {
return;
}
if (mode.length === 1) {
this.animateSwipe(
mode,
range[mode],
direction === 'right' || direction === 'down' ? -velocity : velocity
);
return;
}

const { x, y } = points[0];

Expand Down
9 changes: 7 additions & 2 deletions packages/f2/src/components/zoom/zoomUtil.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ScaleValues, ZoomRange } from './index';
import { Scale, getTickMethod } from '../../deps/f2-scale/src';
import { getRange } from '@antv/util';
import { getRange, isArray } from '@antv/util';
import { toTimeStamp } from '../../util';

// 判断新老values是否相等,这里只要判断前后是否相等即可
Expand Down Expand Up @@ -91,7 +91,12 @@ function updateFollow(scales: Scale[], mainScale: Scale, data) {
data.forEach((item) => {
const value = mainType === 'timeCat' ? toTimeStamp(item[mainField]) : item[mainField];
if (mainValuesMap[value]) {
values.push(item[followField]);
const followItemValue = item[followField];
if (isArray(followItemValue)) {
values.push(...followItemValue);
} else {
values.push(followItemValue);
}
}
});
return updateScale(scale, values);
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/f2/test/components/candlestick/basic.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ describe('candlestick', () => {
expect(context).toMatchImageSnapshot();
});

it.only('tooltip', async () => {
it('tooltip', async () => {
const { props } = (
<Canvas context={context} animate={false} pixelRatio={1}>
<Chart data={data}>
Expand Down

0 comments on commit 95a2c50

Please sign in to comment.