Skip to content

Commit

Permalink
ui-manchette: first version of proportional manchette
Browse files Browse the repository at this point in the history
This first version is still in development, there is some questions about which operationnal point hide or not
  • Loading branch information
Math-R committed May 23, 2024
1 parent eaf7d1f commit b6a1104
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 15 deletions.
13 changes: 11 additions & 2 deletions ui-manchette/src/components/Manchette.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ import { ZoomIn, ZoomOut } from '@osrd-project/ui-icons';
interface ManchetteProps {
operationalPoints: OperationalPointType[];
children?: React.ReactNode;
isProportionnal?: boolean;
}

const Manchette: React.FC<ManchetteProps> = ({ operationalPoints, children }) => {
const Manchette: React.FC<ManchetteProps> = ({
operationalPoints,
children,
isProportionnal = false,
}) => {
const [zoom, setZoom] = React.useState(1);

const zoomIn = () => {
Expand All @@ -22,7 +27,11 @@ const Manchette: React.FC<ManchetteProps> = ({ operationalPoints, children }) =>
return (
<div className="manchette flex">
<div className="manchette-container">
<OperationalPointList operationalPoints={operationalPoints} zoom={zoom} />
<OperationalPointList
operationalPoints={operationalPoints}
zoom={zoom}
isProportionnal={isProportionnal}
/>
<div className="manchette-actions flex items-center">
<div className=" flex items-center ">
<button className="h-full px-3 w-full" onClick={zoomOut} disabled={zoom === 1}>
Expand Down
6 changes: 2 additions & 4 deletions ui-manchette/src/components/OperationalPoint.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import React from 'react';
import { OperationalPointType } from '../types/pathPropertiesTypes';
import '@osrd-project/ui-core/dist/theme.css';
import { positionKm } from './helpers';

const OperationalPoint: React.FC<OperationalPointType> = ({ extensions, id, part, position }) => {
const positionKm = () => {
return Math.round((position / 1000000) * 10) / 10;
};
return (
<div className="flex op items-baseline" id={id}>
<div className="op-position justify-self-start text-end">{positionKm()}</div>
<div className="op-position justify-self-start text-end">{positionKm(position)}</div>

<div className="op-name mr-2 ml-2 justify-self-start">{extensions?.identifier?.name}</div>
<div className="op-separator"></div>
Expand Down
62 changes: 54 additions & 8 deletions ui-manchette/src/components/OperationalPointList.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react';
import React, { useEffect } from 'react';
import { OperationalPointType } from '../types/pathPropertiesTypes';
import OperationalPoint from './OperationalPoint';
import cx from 'classnames';
import { positionKm } from './helpers';

interface OperationalPointListProps {
operationalPoints: OperationalPointType[];
Expand All @@ -15,23 +16,68 @@ const OperationalPointList: React.FC<OperationalPointListProps> = ({
isProportionnal = false,
zoom = 1,
}) => {
const baseHeight = 24;
const operationalPointHeight = (op: OperationalPointType) => {
const [operationalPointsToDisplay, setOperationalPointsToDisplay] = React.useState<
OperationalPointType[]
>([]);
const baseHeight = 32;

const operationalPointStyle = (op: OperationalPointType, nextOp: OperationalPointType) => {
if (isProportionnal) {
// WIP : Ratio to find
return '100%';
if (!nextOp) {
return { height: `${baseHeight}px` };
} else {
return { height: `${positionKm(nextOp.position - op.position) * zoom * 8}px` };
}
} else {
return baseHeight * zoom;
return { height: `${baseHeight * zoom}px` };
}
};

useEffect(() => {
const calcOperationalPointsToDisplay = () => {
if (isProportionnal) {
const result = operationalPoints.reduce(
(acc, nextOp) => {
const op = acc[acc.length - 1];
const diff = positionKm(nextOp.position - op.position);
if (diff * 8 * zoom >= baseHeight) {
acc.push(nextOp);
}
return acc;
},
[operationalPoints[0]]
);

const lastElement = operationalPoints[operationalPoints.length - 1];
if (result[result.length - 1] !== lastElement) {
result.push(lastElement);
}

const secondLastIndex = result.length - 2;
if (secondLastIndex >= 0) {
const secondLastElement = result[secondLastIndex];
const lastDiff = positionKm(lastElement.position - secondLastElement.position);
if (lastDiff * 8 * zoom < baseHeight) {
result.splice(secondLastIndex, 1);
}
}

return result;
} else {
return operationalPoints;
}
};
setOperationalPointsToDisplay(calcOperationalPointsToDisplay());
}, [operationalPoints, isProportionnal, zoom]);

return (
<div className="operational-point-list">
{operationalPoints.map((op, index, { length }) => (
{operationalPointsToDisplay.map((op, index) => (
//WIP : length will be usefull for proportionnal display
<div
key={index}
className={cx('operational-point-wrapper flex flex-col justify-start', {})}
style={{ height: operationalPointHeight(op) }}
style={operationalPointStyle(op, operationalPointsToDisplay[index + 1])}
>
<OperationalPoint {...op} />
</div>
Expand Down
3 changes: 3 additions & 0 deletions ui-manchette/src/components/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const positionKm = (position: number) => {
return Math.round((position / 1000000) * 10) / 10;
};
1 change: 0 additions & 1 deletion ui-manchette/src/styles/operational-point-list.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
.operational-point-list {
width: 349px;
overflow: auto;
border-bottom-left-radius: 0.25rem;

@apply bg-ambientB-10;
Expand Down

0 comments on commit b6a1104

Please sign in to comment.