Skip to content

Commit

Permalink
[Timeline]: fixed Fit Content functionality.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kuznietsov committed Jul 17, 2024
1 parent 494118d commit 7eaf701
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 56 deletions.
19 changes: 12 additions & 7 deletions app/src/demo/tables/editableTable/ProjectTableDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,20 @@ export function ProjectTableDemo() {
});
}, [setValue]);

const timelineController = useMemo(() => {
const { from, to } = getMinMaxDate(treeRef.current);
const timelineController = useMemo(
() => new TimelineController({ widthPx: 0, center: new Date(), pxPerMs: 32 / msPerDay }),
[],
);
const prevWidthPx = usePrevious(timelineController.currentViewport?.widthPx);

const timeController = new TimelineController({ widthPx: 0, center: new Date(), pxPerMs: 32 / msPerDay });
if (from && to) {
timeController.setViewportRange({ from, to, widthPx: 0 }, false);
useEffect(() => {
if (!prevWidthPx && timelineController.currentViewport.widthPx) {
const { from, to } = getMinMaxDate(treeRef.current);
if (from && to) {
timelineController.setViewportRange({ from, to, widthPx: timelineController.currentViewport.widthPx }, false);
}
}
return timeController;
}, []);
}, [timelineController, timelineController.currentViewport.widthPx, prevWidthPx]);

const handleCanAcceptDrop = useCallback((params: AcceptDropParams<Task & { isTask: boolean }, Task>) => {
if (!params.srcData.isTask || params.srcData.id === params.dstData.id) {
Expand Down
31 changes: 7 additions & 24 deletions uui-timeline/src/TimelineController.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { Viewport, ViewportRange } from './types';
import { getScaleByRange, msPerDay, scaleSteps } from './helpers';
import { changeZoomStep, getScaleByRange, msPerDay, scaleSteps } from './helpers';
import { TimelineTransform } from '../';
import sortedIndex from 'lodash.sortedindex';
import { isClientSide } from '@epam/uui-core';
Expand Down Expand Up @@ -88,9 +88,8 @@ export class TimelineController {
}

public setViewportRange(newViewportRange: ViewportRange, doAnimation: boolean) {
const rangeTimestamp = newViewportRange.to.getTime() - newViewportRange.from.getTime();
const centerTimestamp = Math.floor((newViewportRange.to.getTime() + newViewportRange.from.getTime()) / 2);
const pxPerMs = getScaleByRange(rangeTimestamp);
const pxPerMs = getScaleByRange(newViewportRange, this.options);

const center = new Date();
center.setTime(centerTimestamp);
Expand Down Expand Up @@ -133,7 +132,7 @@ export class TimelineController {
public handleWheelEvent = (e: WheelEvent) => {
const vp = this.currentViewport;
const sign = e.deltaY ? (e.deltaY < 0 ? 1 : -1) : 0;
const pxPerMs = this.changeZoomStep(sign);
const pxPerMs = changeZoomStep(sign, this.targetViewport.pxPerMs, this.options);

this.setViewport(
{
Expand All @@ -146,24 +145,6 @@ export class TimelineController {
e.preventDefault();
};

private changeZoomStep(steps: number) {
const currentStep = sortedIndex(scaleSteps, this.targetViewport.pxPerMs);
let targetStep = currentStep + steps;
if (targetStep < 0) {
targetStep = 0;
}
if (targetStep >= scaleSteps.length) {
targetStep = scaleSteps.length - 1;
}
if (scaleSteps[targetStep] > this.options.maxScale) {
targetStep = sortedIndex(scaleSteps, this.options.maxScale);
}
if (scaleSteps[targetStep] < this.options.minScale) {
targetStep = sortedIndex(scaleSteps, this.options.minScale);
}
return scaleSteps[targetStep];
}

public moveToday() {
this.setViewport(
{
Expand Down Expand Up @@ -203,7 +184,7 @@ export class TimelineController {

public zoomBy(steps: number) {
const vp = this.targetViewport;
const pxPerMs = this.changeZoomStep(steps);
const pxPerMs = changeZoomStep(steps, this.targetViewport.pxPerMs, this.options);

this.setViewport(
{
Expand All @@ -215,7 +196,9 @@ export class TimelineController {
}

public canZoomBy(steps: number) {
return this.changeZoomStep(steps) != this.targetViewport.pxPerMs;
const pxPerMs = changeZoomStep(steps, this.targetViewport.pxPerMs, this.options);

return pxPerMs != this.targetViewport.pxPerMs;
}

public getTransform() {
Expand Down
49 changes: 24 additions & 25 deletions uui-timeline/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import sortedIndex from 'lodash.sortedindex';
import { TimelineControllerOptions } from './TimelineController';
import { i18n } from './i18n';
import { ViewportRange } from './types';

export const baseDate = new Date(2000, 1, 1);
export const msPerMinute = 60 /* sec */ * 1000; /* ms */
Expand Down Expand Up @@ -69,32 +72,28 @@ export function getleftXforCentering(stageSegment: any, textWidth: number, paddi
return leftX;
}

export const getScaleByRange = (range: number) => {
const periodToScales: Array<[number, number[]]> = [
[msPerYear, [scales.year, scales.yearWide]],
[msPerMonth, [scales.month, scales.monthWide]],
[msPerWeak, [scales.week, scales.weekWide]],
[msPerDay, [scales.day, scales.dayWide]],
[msPerHour, [scales.hour, scales.hourWide]],
[msPerMinute, [scales.minute, scales.minuteWide]],
];

for (const [index, [period, [gtScale, lteScale]]] of periodToScales.entries()) {
if (range > period) {
return gtScale;
}

const isLastScale = index === periodToScales.length - 1;
if (range === period || isLastScale) {
return lteScale;
}

const [nextPeriod] = periodToScales[index + 1];

if (Math.abs(period - range) <= Math.abs(nextPeriod - range)) {
return lteScale;
}
export const changeZoomStep = (steps: number, pxPerMs: number, options: TimelineControllerOptions) => {
const currentStep = sortedIndex(scaleSteps, pxPerMs);
let targetStep = currentStep + steps;
if (targetStep < 0) {
targetStep = 0;
}
if (targetStep >= scaleSteps.length) {
targetStep = scaleSteps.length - 1;
}
if (scaleSteps[targetStep] > options.maxScale) {
targetStep = sortedIndex(scaleSteps, options.maxScale);
}
if (scaleSteps[targetStep] < options.minScale) {
targetStep = sortedIndex(scaleSteps, options.minScale);
}

return scaleSteps[targetStep];
};

export const getScaleByRange = (viewportRange: ViewportRange, options: TimelineControllerOptions) => {
const pxPerMs = viewportRange.widthPx / (viewportRange.to.getTime() - viewportRange.from.getTime());
return changeZoomStep(-1, pxPerMs, options);
};

export const months = i18n.months;
Expand Down

0 comments on commit 7eaf701

Please sign in to comment.