Skip to content

Commit

Permalink
Merge pull request #190 from devexperts/fix-y-axis-multi-touch-behavior
Browse files Browse the repository at this point in the history
Fix y axis multi touch behavior
  • Loading branch information
KirillBobkov authored Jul 23, 2024
2 parents ee1c76a + fc259b0 commit 7ce8731
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 12 deletions.
3 changes: 2 additions & 1 deletion src/chart/components/pan/chart-pan.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { CanvasAnimation } from '../../animation/canvas-animation';
import { CanvasBoundsContainer } from '../../canvas/canvas-bounds-container';
import { CanvasBoundsContainer, CanvasElement } from '../../canvas/canvas-bounds-container';
import { FullChartConfig } from '../../chart.config';
import EventBus from '../../events/event-bus';
import { ChartBaseElement } from '../../model/chart-base-element';
Expand Down Expand Up @@ -47,6 +47,7 @@ export class ChartPanComponent extends ChartBaseElement {
this.mainScale,
this.canvasInputListener,
this.mainCanvasParent,
this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.ALL_PANES),
);
this.addChildEntity(this.mainCanvasTouchHandler);
}
Expand Down
28 changes: 20 additions & 8 deletions src/chart/components/x_axis/x-axis-scale.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { ChartBaseElement } from '../../model/chart-base-element';
import { CanvasBoundsContainer, CanvasElement } from '../../canvas/canvas-bounds-container';
import { CanvasBoundsContainer, CanvasElement, HitBoundsTest } from '../../canvas/canvas-bounds-container';
import { CanvasInputListenerComponent } from '../../inputlisteners/canvas-input-listener.component';
import { ScaleModel } from '../../model/scale.model';
import { Pixel, Unit } from '../../model/scaling/viewport.model';
Expand All @@ -24,6 +24,8 @@ export class XAxisScaleHandler extends ChartBaseElement {
lastXPxWidth: Pixel = 0;

private dblClickCallback: () => void;

private touches: TouchList | undefined;
private dblTapCallback: () => void;

constructor(
Expand All @@ -32,6 +34,7 @@ export class XAxisScaleHandler extends ChartBaseElement {
private canvasBoundsContainer: CanvasBoundsContainer,
private chartPanComponent: ChartPanComponent,
private chartModel: ChartModel,
private hitTest: HitBoundsTest,
private hitTestCanvasModel: HitTestCanvasModel,
) {
super();
Expand All @@ -40,7 +43,7 @@ export class XAxisScaleHandler extends ChartBaseElement {
this.dblTapCallback = () => chartModel.doBasicScale();

const dragNDropXComponent = new DragNDropXComponent(
this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.X_AXIS),
hitTest,
{
onDragStart: this.onXDragStart,
onDragTick: this.onXDragTick,
Expand All @@ -67,14 +70,23 @@ export class XAxisScaleHandler extends ChartBaseElement {
protected doActivate() {
super.doActivate();
this.addRxSubscription(
this.canvasInputListener
.observeDbClick(this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.X_AXIS))
.subscribe(() => this.dblClickCallback()),
this.canvasInputListener.observeDbClick(this.hitTest).subscribe(() => this.dblClickCallback()),
);
this.addRxSubscription(
this.canvasInputListener.observeDbTap(this.hitTest).subscribe(() => {
// apply dbl tap only if single finger taps are made
if (this.touches && this.touches?.length > 1) {
this.touches = undefined;
return;
}

this.dblTapCallback();
}),
);
this.addRxSubscription(
this.canvasInputListener
.observeDbTap(this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.X_AXIS))
.subscribe(() => this.dblTapCallback()),
this.canvasInputListener.observeTouchStart(this.hitTest).subscribe(e => {
this.touches = e.touches;
}),
);
this.addRxSubscription(
this.chartModel.candlesPrependSubject.subscribe(
Expand Down
1 change: 1 addition & 0 deletions src/chart/components/x_axis/x-axis.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export class XAxisComponent extends ChartBaseElement {
canvasBoundsContainer,
chartPanComponent,
this.chartComponent.chartModel,
canvasBoundsContainer.getBoundsHitTest(CanvasElement.X_AXIS),
hitTestCanvasModel,
);
this.addChildEntity(this.xAxisScaleHandler);
Expand Down
25 changes: 24 additions & 1 deletion src/chart/components/y_axis/y-axis-scale.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export class YAxisScaleHandler extends ChartBaseElement {
lastYPxHeight: Pixel = 0;

private dblClickCallback: () => void;

private touches: TouchList | undefined;
private dblTapCallback: () => void;

constructor(
Expand Down Expand Up @@ -78,10 +80,21 @@ export class YAxisScaleHandler extends ChartBaseElement {
);
this.addRxSubscription(
this.canvasInputListener.observeDbTap(this.hitTest).subscribe(() => {
// apply dbl tap only if single finger taps are made
if (this.touches && this.touches?.length > 1) {
this.touches = undefined;
return;
}

this.dblTapCallback();
this.bus.fireDraw();
}),
);
this.addRxSubscription(
this.canvasInputListener.observeTouchStart(this.hitTest).subscribe(e => {
this.touches = e.touches;
}),
);
}
}

Expand All @@ -97,7 +110,17 @@ export class YAxisScaleHandler extends ChartBaseElement {
};

private onYDragTick = (dragInfo: DragInfo) => {
const { delta: absoluteYDelta } = dragInfo;
let { delta: absoluteYDelta } = dragInfo;

// check how many touch events are at the axis
// if multitouch - take the first two and apply delta the following way:
// the touch above keeps the initial delta because top => bottom gesture
// the touch below has the reversed delta because the gesture is bottom => top
if (this.touches && this.touches.length > 1) {
const top = Math.min(this.touches[0].clientY, this.touches[1].clientY);
absoluteYDelta = top === this.touches[0].clientY ? absoluteYDelta : -absoluteYDelta;
}

// 1/3..3
let zoomYMult;
if (absoluteYDelta < 0) {
Expand Down
6 changes: 4 additions & 2 deletions src/chart/inputhandlers/main-canvas-touch.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ChartBaseElement } from '../model/chart-base-element';
import { CanvasInputListenerComponent } from '../inputlisteners/canvas-input-listener.component';
import { ScaleModel } from '../model/scale.model';
import { ChartAreaPanHandler } from '../components/chart/chart-area-pan.handler';
import { HitBoundsTest } from '../canvas/canvas-bounds-container';

/**
* Handles chart touch events.
Expand All @@ -19,6 +20,7 @@ export class MainCanvasTouchHandler extends ChartBaseElement {
private scale: ScaleModel,
private canvasInputListeners: CanvasInputListenerComponent,
private mainCanvasParent: Element,
private hitTest: HitBoundsTest,
) {
super();
}
Expand All @@ -30,10 +32,10 @@ export class MainCanvasTouchHandler extends ChartBaseElement {
*/
protected doActivate(): void {
this.addRxSubscription(
this.canvasInputListeners.observeTouchStart().subscribe(e => this.handleTouchStartEvent(e)),
this.canvasInputListeners.observeTouchStart(this.hitTest).subscribe(e => this.handleTouchStartEvent(e)),
);
this.addRxSubscription(
this.canvasInputListeners.observeTouchMove().subscribe(e => this.handleTouchMoveEvent(e)),
this.canvasInputListeners.observeTouchMove(this.hitTest).subscribe(e => this.handleTouchMoveEvent(e)),
);
this.addRxSubscription(
this.canvasInputListeners.observeTouchEndDocument().subscribe(e => this.handleTouchEndEvent(e)),
Expand Down

0 comments on commit 7ce8731

Please sign in to comment.