Skip to content

Commit

Permalink
Pull request #5315: Feature/DXCF-5652 adaptive x axis time axis pinch…
Browse files Browse the repository at this point in the history
… gesture improvement

Merge in DXCHARTS/dxchart5 from feature/DXCF-5652-adaptive-x-axis-time-axis-pinch-gesture-improvement to master

* commit '8e0df5df2c99a80041e65b994b7635710b48e769':
  [DXCF-5652] [Adaptive] X-axis (time axis) pinch gesture improvement // init
  [DXCF-5652] [Adaptive] X-axis (time axis) pinch gesture improvement // init
  [DXCF-5652] [Adaptive] X-axis (time axis) pinch gesture improvement // init
  [DXCF-5652] [Adaptive] X-axis (time axis) pinch gesture improvement // init
  [DXCF-5652] [Adaptive] X-axis (time axis) pinch gesture improvement // init

GitOrigin-RevId: 533ffd644902c4e3a8cfc7763e891cbbe2b2ff96
  • Loading branch information
Keelaro1 authored and dxcity committed Dec 11, 2024
1 parent 08b9b3c commit f4bab88
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 16 deletions.
6 changes: 5 additions & 1 deletion src/chart/canvas/canvas-bounds-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ const N_MAP_BUTTON_W = 15;
const KNOTS_W_MOBILE_MULTIPLIER = 1.5;
const N_MAP_KNOT_W = isMobile() ? 8 * KNOTS_W_MOBILE_MULTIPLIER : 8;

// additional x axis height padding for mobiles, used for better usability on mobile devices
export const X_AXIS_MOBILE_PADDING = isMobile() ? 5 : 0;

/**
* we need to check that: heightRatios - 1 < 0.000001 after calculations between decimals
*/
Expand Down Expand Up @@ -466,7 +469,8 @@ export class CanvasBoundsContainer {
this.xAxisHeight =
fontHeight +
(this.config.components.xAxis.padding.top ?? 0) +
(this.config.components.xAxis.padding.bottom ?? 0);
(this.config.components.xAxis.padding.bottom ?? 0) +
X_AXIS_MOBILE_PADDING;
}
return this.xAxisHeight;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { CanvasBoundsContainer, CanvasElement } from '../../../canvas/canvas-bounds-container';
import { CanvasBoundsContainer, CanvasElement, X_AXIS_MOBILE_PADDING } from '../../../canvas/canvas-bounds-container';
import { FullChartConfig } from '../../../chart.config';
import { avoidAntialiasing, drawRoundedRect } from '../../../utils/canvas/canvas-drawing-functions.utils';
import { PaneManager } from '../../pane/pane-manager.component';
Expand Down Expand Up @@ -112,12 +112,12 @@ export class CrossAndLabelsDrawerType implements CrossToolTypeDrawer {
const boxWidth = width + xLabelPaddingLeft + xLabelPaddingRight;
const boxHeight = fontHeight + xLabelPaddingTop + xLabelPaddingBottom;
const xBoxPos = Math.max(x - boxWidth / 2, 0);
const yBoxPos = xAxis.y + xLabelMarginTop;
const yBoxPos = xAxis.y + xLabelMarginTop + X_AXIS_MOBILE_PADDING / 2;
drawRoundedRect(ctx, xBoxPos, yBoxPos, boxWidth, boxHeight);
// label
ctx.fillStyle = crossToolColors.labelTextColor;
const xTextPos = Math.max(x - width / 2, xLabelPaddingLeft);
const yTextPos = xAxis.y + xLabelMarginTop + fontHeight + xLabelPaddingTop - 1; // -1 for vertical adjustment
const yTextPos = xAxis.y + xLabelMarginTop + fontHeight + X_AXIS_MOBILE_PADDING / 2 + xLabelPaddingTop - 1; // -1 for vertical adjustment
ctx.fillText(labelText, xTextPos, yTextPos);
ctx.restore();
}
Expand Down
4 changes: 2 additions & 2 deletions src/chart/components/x_axis/x-axis-draw.functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { CanvasBoundsContainer, CanvasElement } from '../../canvas/canvas-bounds-container';
import { CanvasBoundsContainer, CanvasElement, X_AXIS_MOBILE_PADDING } from '../../canvas/canvas-bounds-container';
import { FullChartConfig } from '../../chart.config';
import { XAxisLabel } from './x-axis-labels.model';

Expand Down Expand Up @@ -63,7 +63,7 @@ export function drawXAxisLabel(

ctx.fillStyle = label.color;
const xTextPos = boxStart + DEFAULT_X_LABEL_PADDING.x;
const yTextPos = xAxisBounds.y + offsetTop + fontSize; // -2 for vertical adjustment
const yTextPos = xAxisBounds.y + offsetTop + fontSize + X_AXIS_MOBILE_PADDING / 2;
ctx.fillText(label.text, xTextPos, yTextPos);
ctx.restore();
}
49 changes: 41 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 @@ -14,12 +14,16 @@ import { DragNDropXComponent } from '../dran-n-drop_helper/drag-n-drop-x.compone
import { ChartPanComponent } from '../pan/chart-pan.component';
import { HitTestCanvasModel } from '../../model/hit-test-canvas.model';

// if you drag full X width from left to right - you will have x3 zoom, and vice-versa
const FULL_X_WIDTH_ZOOM_FACTOR = 3;

/**
* Handles the mouse drag on X axis - to zoom the viewport horizontally.
* @doc-tags scaling,zoom,viewport
*/
export class XAxisScaleHandler extends ChartBaseElement {
lastXStart: Unit = 0;
lastXEnd: Unit = 0;
lastXWidth: Unit = 0;
lastXPxWidth: Pixel = 0;

Expand Down Expand Up @@ -97,6 +101,7 @@ export class XAxisScaleHandler extends ChartBaseElement {

private onXDragStart = () => {
this.lastXStart = this.scale.xStart;
this.lastXEnd = this.scale.xEnd;
this.lastXWidth = this.scale.xEnd - this.scale.xStart;
const bounds = this.canvasBoundsContainer.getBounds(CanvasElement.X_AXIS);
this.lastXPxWidth = bounds.width - this.canvasInputListener.currentPoint.x;
Expand All @@ -105,16 +110,44 @@ export class XAxisScaleHandler extends ChartBaseElement {
};

private onXDragTick = (dragInfo: DragInfo) => {
const { delta: absoluteXDelta } = dragInfo;
const newPxWidth = this.lastXPxWidth - absoluteXDelta;
// cursor goes beyond x-axis - maximum scale is reached
if (newPxWidth < 0) {
let { delta: absoluteXDelta } = dragInfo;

// mouse click or single tap drag
if (!this.touches || this.touches.length === 1) {
const newPxWidth = this.lastXPxWidth - absoluteXDelta;
// cursor goes beyond x-axis - maximum scale is reached
if (newPxWidth < 0) {
return;
}
const xZoomMult = this.lastXPxWidth / newPxWidth;
const newWidth = this.lastXWidth * xZoomMult;
const newXStart = this.lastXStart + (this.lastXWidth - newWidth);
this.scale.setXScale(newXStart, this.scale.xEnd);
return;
}
const xZoomMult = this.lastXPxWidth / newPxWidth;
const newWidth = this.lastXWidth * xZoomMult;
const newXStart = this.lastXStart + (this.lastXWidth - newWidth);
this.scale.setXScale(newXStart, this.scale.xEnd);

// if multitouch - take the first two touch events and apply delta the following way:
// the touch on the left keeps the initial delta because left => right gesture
// the touch on the right has the reversed delta because the gesture is right => left
if (this.touches.length > 1) {
const left = Math.min(this.touches[0].clientX, this.touches[1].clientX);
absoluteXDelta = left === this.touches[0].clientX ? absoluteXDelta : -absoluteXDelta;

let xZoomMult;
if (absoluteXDelta < 0) {
xZoomMult = 1 / (1 + (-absoluteXDelta / this.lastXPxWidth) * (FULL_X_WIDTH_ZOOM_FACTOR - 1));
} else {
xZoomMult = 1 + (absoluteXDelta / this.lastXPxWidth) * (FULL_X_WIDTH_ZOOM_FACTOR - 1);
}

const newXWidth = this.lastXWidth * xZoomMult;
const delta = (newXWidth - this.lastXWidth) / 2;
const newXStart = this.lastXStart - delta;
const newXEnd = this.lastXEnd + delta;
if (this.lastXStart !== newXStart || this.lastXEnd !== newXEnd) {
this.scale.setXScale(newXStart, newXEnd);
}
}
};

private onXDragEnd = () => {
Expand Down
4 changes: 2 additions & 2 deletions src/chart/components/x_axis/x-axis-time-labels.drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { NumericAxisLabel } from '../labels_generator/numeric-axis-labels.generator';
import { Bounds } from '../../model/bounds.model';
import { FullChartConfig } from '../../chart.config';
import { CanvasBoundsContainer, CanvasElement } from '../../canvas/canvas-bounds-container';
import { CanvasBoundsContainer, CanvasElement, X_AXIS_MOBILE_PADDING } from '../../canvas/canvas-bounds-container';
import { CanvasModel } from '../../model/canvas.model';
import { Drawer } from '../../drawers/drawing-manager';
import { ViewportModel } from '../../model/scaling/viewport.model';
Expand Down Expand Up @@ -46,7 +46,7 @@ export class XAxisTimeLabelsDrawer implements Drawer {

const color = this.config.colors.xAxis.labelTextColor;
const labels = this.labelsProvider();
this.drawLabels(ctx, labels, bounds, color, fontHeight, fontFamily, offsetTop);
this.drawLabels(ctx, labels, bounds, color, fontHeight, fontFamily, offsetTop + X_AXIS_MOBILE_PADDING / 2);
ctx.restore();
}
}
Expand Down

0 comments on commit f4bab88

Please sign in to comment.