Skip to content

Commit

Permalink
front: insert div in manchette with space time chart
Browse files Browse the repository at this point in the history
Signed-off-by: theocrsb <[email protected]>
  • Loading branch information
theocrsb committed Mar 7, 2025
1 parent 57effe7 commit f6ffc85
Show file tree
Hide file tree
Showing 23 changed files with 175 additions and 57 deletions.
6 changes: 1 addition & 5 deletions storybook/stories/ManchetteSplit/ManchetteSplit.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,7 @@ const meta: Meta<typeof Manchette> = {
export default meta;
type Story = StoryObj<typeof Manchette>;

const customDiv = (
<div style={{ height: 'auto', minHeight: 24, backgroundColor: 'rgba(152, 192, 245, 1)' }}>
Hello World
</div>
);
const customDiv = <div style={{ height: '100px', backgroundColor: '#EFF3F5' }} />;

export const Default: Story = {
args: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import React, { useRef } from 'react';

import { PathLayer, SpaceTimeChart, type SpaceTimeChartProps } from '../../../spaceTimeChart';
import {
PathLayer,
SpaceTimeChart,
isInteractiveWaypoint,
type SpaceTimeChartProps,
} from '../../../spaceTimeChart';
import Manchette, {
type ProjectPathTrainResult,
type Waypoint,
type ManchetteProps,
type InteractiveWaypoint,
} from '../../Manchette';
import useManchetteWithSpaceTimeChart from '../hooks/useManchetteWithSpaceTimeChart';

export type ManchetteWithSpaceTimeChartProps = {
waypoints: Waypoint[];
contents: (InteractiveWaypoint | React.ReactNode)[];
projectPathTrainResult: ProjectPathTrainResult[];
selectedTrain?: number;
height?: number;
Expand All @@ -26,7 +32,7 @@ export type ManchetteWithSpaceTimeChartProps = {
* and space time chart, the useManchetteWithSpaceTimeChart() hook can be used.
*/
const ManchetteWithSpaceTimeChart = ({
waypoints,
contents,
projectPathTrainResult,
selectedTrain,
height = 561,
Expand All @@ -39,7 +45,7 @@ const ManchetteWithSpaceTimeChart = ({
const spaceTimeChartRef = useRef<HTMLDivElement>(null);

const { manchetteProps, spaceTimeChartProps, handleScroll } = useManchetteWithSpaceTimeChart(
waypoints,
contents,
projectPathTrainResult,
manchetteWithSpaceTimeChartRef,
selectedTrain,
Expand Down Expand Up @@ -74,9 +80,13 @@ const ManchetteWithSpaceTimeChart = ({
{...spaceTimeChartProps}
{...additionalSpaceTimeChartProps}
>
{spaceTimeChartProps.paths.map((path) => (
<PathLayer key={path.id} path={path} color={path.color} level={path.level} />
))}
{spaceTimeChartProps.paths.map((path, index) =>
path.id ? (
<PathLayer key={path.id} path={path} color={path.color} level={path.level} />
) : (
<div key={index}>{'coucou'}</div>
)
)}
{children}
</SpaceTimeChart>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ export const filterVisibleElements = (
return displayedElements.sort((a, b) => a.position - b.position);
};

export const isInteractiveWaypoint = (
item: InteractiveWaypoint | React.ReactNode
): item is InteractiveWaypoint =>
item != null && typeof item === 'object' && 'id' in item && 'position' in item;

export const computeWaypointsToDisplay = (
waypoints: Waypoint[],
{ height, isProportional, yZoom }: WaypointsOptions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { useCallback, useEffect, useMemo, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';


import usePaths from './usePaths';
import type { SpaceScale, SpaceTimeChartProps } from '../../../spaceTimeChart';
import type { ProjectPathTrainResult, Waypoint } from '../../Manchette';
import type { ProjectPathTrainResult, Waypoint, InteractiveWaypoint } from '../../Manchette';
import { MAX_ZOOM_Y, MIN_ZOOM_Y, ZOOM_Y_DELTA, DEFAULT_ZOOM_MS_PER_PX } from '../consts';
import {
computeWaypointsToDisplay,
getScales,
zoomX,
zoomValueToTimeScale,
timeScaleToZoomValue,
isInteractiveWaypoint,
} from '../helpers';
import { getDiff } from '../utils/point';

Expand All @@ -27,8 +29,17 @@ type State = {
scales: SpaceScale[];
};

type SimplifiedWaypoint = {
id: string;
label: string;
position: number;
importanceLevel: number;
};

type SimplifiedWaypoints = (SimplifiedWaypoint | React.ReactNode)[];

const useManchettesWithSpaceTimeChart = (
waypoints: Waypoint[],
contents: (InteractiveWaypoint | React.ReactNode)[],
projectPathTrainResult: ProjectPathTrainResult[],
manchetteWithSpaceTimeChartContainer: React.RefObject<HTMLDivElement>,
selectedTrain?: number,
Expand All @@ -47,6 +58,7 @@ const useManchettesWithSpaceTimeChart = (
waypointsChart: [],
scales: [],
});
const waypoints = useMemo(() => contents.filter(isInteractiveWaypoint), [contents]);

const { xZoom, yZoom, xOffset, yOffset, scrollTo, panning, isProportional } = state;

Expand Down Expand Up @@ -148,9 +160,19 @@ const useManchettesWithSpaceTimeChart = (
[simplifiedWaypoints, height, isProportional, yZoom]
);

const contentsToDisplay = useMemo(
() =>
contents.map((content) =>
isInteractiveWaypoint(content)
? waypointsToDisplay.find((wp) => wp.id === content.id) || content
: content
),
[contents, waypointsToDisplay]
);

const manchetteProps = useMemo(
() => ({
contents: waypointsToDisplay,
contents: contentsToDisplay,
zoomYIn,
zoomYOut,
resetZoom,
Expand All @@ -159,7 +181,7 @@ const useManchettesWithSpaceTimeChart = (
isProportional,
yOffset,
}),
[waypointsToDisplay, zoomYIn, zoomYOut, resetZoom, toggleMode, yZoom, isProportional, yOffset]
[contentsToDisplay, zoomYIn, zoomYOut, resetZoom, toggleMode, yZoom, isProportional, yOffset]
);

const handleXZoom = useCallback(
Expand All @@ -174,7 +196,7 @@ const useManchettesWithSpaceTimeChart = (

const spaceTimeChartProps = useMemo(
() => ({
operationalPoints: simplifiedWaypoints,
contents: simplifiedWaypoints,
spaceScales: computedScales,
timeScale: zoomValueToTimeScale(xZoom),
paths,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default meta;

export const Default = {
args: {
waypoints: SAMPLE_WAYPOINTS,
contents: SAMPLE_WAYPOINTS,
projectPathTrainResult: SAMPLE_PATHS_DATA,
selectedTrain: 1,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';

import type { Meta } from '@storybook/react';

import '@osrd-project/ui-core/dist/theme.css';
import '@osrd-project/ui-charts/dist/theme.css';

import { SAMPLE_WAYPOINTS, SAMPLE_PATHS_DATA } from '../assets/sampleData';
import ManchetteWithSpaceTimeChart from '../components/ManchetteWithSpaceTimeChart';

const meta: Meta<typeof ManchetteWithSpaceTimeChart> = {
title: 'Manchette with SpaceTimeChart/split',
component: ManchetteWithSpaceTimeChart,
};

const customDiv = <div style={{ height: '100px', backgroundColor: '#EFF3F5' }} />;

const allWaypoints = SAMPLE_WAYPOINTS.map((waypoint, index) => {
if (index === 0 || index === 1 || index === 3) {
return [waypoint, customDiv];
}
return waypoint;
}).flat();

export default meta;

export const Default = {
args: {
contents: allWaypoints,
projectPathTrainResult: SAMPLE_PATHS_DATA,
selectedTrain: 1,
},
};
35 changes: 27 additions & 8 deletions ui-charts/src/spaceTimeChart/components/PathLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import {
type DataPoint,
DEFAULT_PATH_END,
type DrawingFunction,
type OperationalPoint,
type PathData,
type PickingDrawingFunction,
type Point,
type SpaceTimeChartContextType,
InteractiveWaypoint,
OperationalPoint,
} from '../lib/types';
import {
drawAliasedDisc,
Expand Down Expand Up @@ -68,6 +69,20 @@ export type PathLayerProps = {
level?: PathLevel;
};

export const isInteractiveWaypoint = (
item: InteractiveWaypoint | React.ReactNode
): item is InteractiveWaypoint | OperationalPoint =>
item != null && typeof item === 'object' && 'id' in item && 'position' in item;

export const isOp = (
item: InteractiveWaypoint | React.ReactNode | OperationalPoint
): item is OperationalPoint =>
item != null &&
typeof item === 'object' &&
'id' in item &&
'position' in item &&
'importanceLevel' in item;

/**
* This component handles drawing a Path inside a SpaceTimeChart. It renders:
* - The path itself
Expand Down Expand Up @@ -134,6 +149,7 @@ export const PathLayer = ({
},
[path]
);

/**
* This function returns the list of important points, where the mouse can snap.
*/
Expand All @@ -143,10 +159,11 @@ export const PathLayer = ({
getSpacePixel,
timeAxis,
spaceAxis,
operationalPoints,
contents,
}: SpaceTimeChartContextType): Point[] => {
const res: Point[] = [];
const stopPositions = new Set(operationalPoints.map((p) => p.position));
const waypoints = contents.filter(isInteractiveWaypoint);
const stopPositions = new Set(waypoints.map((p) => p.position));
path.points.forEach(({ position, time }) => {
if (stopPositions.has(position))
res.push({
Expand All @@ -163,8 +180,9 @@ export const PathLayer = ({
* This function draws the stops of the path on the operational points.
*/
const drawPauses = useCallback<DrawingFunction>(
(ctx, { getTimePixel, getSpacePixel, operationalPoints, swapAxis }) => {
const stopPositions = new Set(operationalPoints.map((p) => p.position));
(ctx, { getTimePixel, getSpacePixel, contents, swapAxis }) => {
const waypoints = contents.filter(isInteractiveWaypoint);
const stopPositions = new Set(waypoints.map((p) => p.position));
path.points.forEach(({ position, time }, i, a) => {
if (i) {
const { position: prevPosition, time: prevTime } = a[i - 1];
Expand Down Expand Up @@ -309,11 +327,12 @@ export const PathLayer = ({
);

const computePathLength = useCallback(
(operationalPoints: OperationalPoint[], segments: Point[]) => {
(contents: (InteractiveWaypoint | React.ReactNode)[], segments: Point[]) => {
let totalLength = 0;
const waypoints = contents.filter(isInteractiveWaypoint);

// Compute length of pauses
const stopPositions = new Set(operationalPoints.map((p) => p.position));
const stopPositions = new Set(waypoints.map((p) => p.position));
path.points.forEach(({ position, time }, i, pointsArray) => {
if (i > 0) {
const { position: prevPosition, time: prevTime } = pointsArray[i - 1];
Expand Down Expand Up @@ -371,7 +390,7 @@ export const PathLayer = ({

// Draw label:
if (!stcContext.hidePathsLabels) {
const pathLength = computePathLength(stcContext.operationalPoints, segments);
const pathLength = computePathLength(stcContext.contents, segments);
drawLabel(ctx, stcContext, path.label, color, segments, pathLength);
}
},
Expand Down
6 changes: 5 additions & 1 deletion ui-charts/src/spaceTimeChart/components/SpaceGraduations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useDraw } from '../hooks/useCanvas';
import { type DrawingFunction } from '../lib/types';
import { getCrispLineCoordinate } from '../utils/canvas';
import { getSpacePixels } from '../utils/paths';
import { isInteractiveWaypoint, isOp } from './PathLayer';

const SpaceGraduations = () => {
const drawingFunction = useCallback<DrawingFunction>(
Expand All @@ -12,7 +13,7 @@ const SpaceGraduations = () => {
{
timePixelOffset,
getSpacePixel,
operationalPoints,
contents,
swapAxis,
width,
height,
Expand All @@ -21,6 +22,9 @@ const SpaceGraduations = () => {
) => {
const axisSize = !swapAxis ? width : height;

const waypoints = contents.filter(isInteractiveWaypoint);
const operationalPoints = waypoints.filter(isOp);

// Draw operational point lines:
operationalPoints.forEach((point) => {
const styles = spaceGraduationsStyles[point.importanceLevel || 0];
Expand Down
8 changes: 4 additions & 4 deletions ui-charts/src/spaceTimeChart/components/SpaceTimeChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { snapPosition } from '../utils/snapping';

export const SpaceTimeChart = (props: SpaceTimeChartProps) => {
const {
operationalPoints,
contents,
spaceOrigin,
spaceScales,
timeOrigin,
Expand Down Expand Up @@ -63,7 +63,7 @@ export const SpaceTimeChart = (props: SpaceTimeChartProps) => {
const fingerprint = useMemo(
() =>
JSON.stringify({
operationalPoints,
contents,
width,
height,
spaceOrigin,
Expand All @@ -78,7 +78,7 @@ export const SpaceTimeChart = (props: SpaceTimeChartProps) => {
showTicks,
}),
[
operationalPoints,
contents,
width,
height,
spaceOrigin,
Expand Down Expand Up @@ -140,7 +140,7 @@ export const SpaceTimeChart = (props: SpaceTimeChartProps) => {
pickingElements,
resetPickingElements,
registerPickingElement,
operationalPoints,
contents,
spaceOrigin,
spaceScaleTree,
timeOrigin,
Expand Down
Loading

0 comments on commit f6ffc85

Please sign in to comment.