Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

charts: add weight property to operational points #744

Merged
merged 2 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions ui-manchette-with-spacetimechart/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"dependencies": {
"@osrd-project/ui-manchette": "0.0.1-dev",
"@osrd-project/ui-spacetimechart": "0.0.1-dev",
"@osrd-project/ui-speedspacechart": "0.0.1-dev",
"classnames": "^2.5.1",
"lodash.isequal": "^4.5.0",
"vitest": "^2.1.1"
Expand Down
10 changes: 5 additions & 5 deletions ui-manchette-with-spacetimechart/src/__tests__/helpers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { describe, it, expect } from 'vitest';

import { BASE_WAYPOINT_HEIGHT } from '../consts';
import {
calcWaypointsToDisplay,
getDisplayedWaypoints,
calcWaypointsHeight,
getWaypointsWithPosition,
getScales,
Expand All @@ -17,9 +17,9 @@ const mockedWaypoints = [
{ position: 20, id: 'waypoint-3' },
];

describe('calcWaypointsToDisplay', () => {
describe('getDisplayedWaypoints', () => {
it('should display all points for non-proportional display', () => {
const result = calcWaypointsToDisplay(mockedWaypoints, {
const result = getDisplayedWaypoints(mockedWaypoints, {
height: 500,
isProportional: false,
yZoom: 1,
Expand All @@ -31,7 +31,7 @@ describe('calcWaypointsToDisplay', () => {
});

it('should calculate proportional display correctly', () => {
const result = calcWaypointsToDisplay(mockedWaypoints, {
const result = getDisplayedWaypoints(mockedWaypoints, {
height: 500,
isProportional: true,
yZoom: 1,
Expand All @@ -42,7 +42,7 @@ describe('calcWaypointsToDisplay', () => {
});

it('should ensure the last point is always displayed', () => {
const result = calcWaypointsToDisplay(mockedWaypoints, {
const result = getDisplayedWaypoints(mockedWaypoints, {
height: 500,
isProportional: true,
yZoom: 1,
Expand Down
22 changes: 22 additions & 0 deletions ui-manchette-with-spacetimechart/src/assets/sampleData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,132 +7,154 @@ export const SAMPLE_WAYPOINTS: Waypoint[] = [
position: 0,
name: 'Brest',
secondaryCode: 'BV',
weight: 100,
},
{
id: '2',
position: 3983000,
name: 'Le Rody',
secondaryCode: '00',
weight: 60,
},
{
id: '3',
position: 7349000,
name: 'Kerhuon',
secondaryCode: 'BV',
weight: 50,
},
{
id: '4',
position: 13882000,
name: 'La Forest',
secondaryCode: '00',
weight: 40,
},
{
id: '5',
position: 18756000,
name: 'Landerneau',
secondaryCode: 'BV',
weight: 30,
},
{
id: '6',
position: 23358000,
name: 'La Roche',
secondaryCode: '00',
weight: 35,
},
{
id: '7',
position: 33219000,
name: 'Landivisiau',
secondaryCode: '00',
weight: 70,
},
{
id: '8',
position: 40612000,
name: 'Guimiliau',
secondaryCode: '00',
weight: 40,
},
{
id: '9',
position: 44960000,
name: 'St-Thégonnec',
secondaryCode: '00',
weight: 50,
},
{
id: '10',
position: 50471000,
name: 'Pleyber-Christ',
secondaryCode: '00',
weight: 45,
},
{
id: '11',
position: 59554000,
name: 'Morlaix',
secondaryCode: 'BV',
weight: 20,
},
{
id: '12',
position: 68903000,
name: 'Plouigneau',
secondaryCode: '00',
weight: 15,
},
{
id: '13',
position: 83194000,
name: 'Plounérin',
secondaryCode: '00',
weight: 10,
},
{
id: '14',
position: 91392000,
name: 'Plouaret',
secondaryCode: '00',
weight: 0,
},
{
id: '15',
position: 102478000,
name: 'Belle-Isle-Bégard',
secondaryCode: '00',
weight: 60,
},
{
id: '16',
position: 117570000,
name: 'Guingamp',
secondaryCode: '00',
weight: 90,
},
{
id: '17',
position: 130463000,
name: 'Châtelaudren-Plouagat',
secondaryCode: 'BV',
weight: 20,
},
{
id: '18',
position: 137315000,
name: 'Plouvara-Plerneuf',
secondaryCode: '00',
weight: 40,
},
{
id: '19',
position: 141157000,
name: 'La Méaugon',
secondaryCode: '00',
weight: 45,
},
{
id: '20',
position: 147745000,
name: 'St-Brieuc',
secondaryCode: 'BV',
weight: 70,
},
{
id: '21',
position: 157361000,
name: 'Yffiniac',
secondaryCode: '00',
weight: 0,
},
{
id: '22',
position: 168056000,
name: 'Lamballe',
secondaryCode: 'BV',
weight: 100,
},
];

Expand Down
41 changes: 10 additions & 31 deletions ui-manchette-with-spacetimechart/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { InteractiveWaypoint, Waypoint } from '@osrd-project/ui-manchette/dist/types';
import type { OperationalPoint } from '@osrd-project/ui-spacetimechart/dist/lib/types';
import { filterVisibleElements } from '@osrd-project/ui-speedspacechart/src/components/utils';
import { clamp } from 'lodash';

import {
Expand All @@ -13,48 +14,26 @@ import { calcTotalDistance, getHeightWithoutLastWaypoint } from './utils';

type WaypointsOptions = { isProportional: boolean; yZoom: number; height: number };

export const calcWaypointsToDisplay = (
export const getDisplayedWaypoints = (
waypoints: Waypoint[],
{ height, isProportional, yZoom }: WaypointsOptions
): InteractiveWaypoint[] => {
if (!isProportional || waypoints.length === 0) {
// For non-proportional display, we always display all the waypoints:
return waypoints.map((waypoint) => ({ ...waypoint, display: true }));
}

// For proportional display, we only display waypoints that do not overlap with
// the last displayed point:
const result: InteractiveWaypoint[] = [{ ...waypoints[0], display: true }];
const totalDistance = calcTotalDistance(waypoints);
const heightWithoutFinalWaypoint = getHeightWithoutLastWaypoint(height);
let lastDisplayedWaypoint = result[0];

// We iterate through all points, and only add them if they don't collide
// with the last visible point:
for (let i = 1; i < waypoints.length; i++) {
const waypoint = waypoints[i];
const diff = waypoint.position - lastDisplayedWaypoint.position;
const display =
(diff / totalDistance) * heightWithoutFinalWaypoint * yZoom >= BASE_WAYPOINT_HEIGHT;

if (display) {
result.push({ ...waypoint, display });
lastDisplayedWaypoint = waypoint;
}
}
const minSpace = BASE_WAYPOINT_HEIGHT / yZoom;

// In the end, to make sure the last point is visible, if it's not, we swap
// it with the last visible item:
const lastItem = result[result.length - 1];
if (!lastItem.display) {
const lastVisibleItem = result.findLast((waypoint) => waypoint.display);
if (lastVisibleItem) {
lastVisibleItem.display = false;
lastItem.display = true;
}
}
const displayedWaypoints = filterVisibleElements({
elements: waypoints,
getPosition: (waypoint) => (waypoint.position / totalDistance) * heightWithoutFinalWaypoint,
getWeight: (waypoint) => waypoint.weight,
minSpace,
});

return result;
return displayedWaypoints.map((waypoint) => ({ ...waypoint, display: true }));
};

export const calcWaypointsHeight = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
DEFAULT_ZOOM_MS_PER_PX,
} from '../consts';
import {
calcWaypointsToDisplay,
getDisplayedWaypoints,
getWaypointsWithPosition as getOperationalPointWithPosition,
getScales,
calcWaypointsHeight,
Expand Down Expand Up @@ -63,7 +63,7 @@ const useManchettesWithSpaceTimeChart = (
const paths = usePaths(projectPathTrainResult, selectedTrain);

const waypointsToDisplay = useMemo(
() => calcWaypointsToDisplay(waypoints, { height, isProportional, yZoom }),
() => getDisplayedWaypoints(waypoints, { height, isProportional, yZoom }),
[waypoints, height, isProportional, yZoom]
);
const waypointWithHeight = useMemo(
Expand Down
4 changes: 4 additions & 0 deletions ui-manchette/src/stories/assets/sampleData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,27 @@ export const SAMPLE_WAYPOINTS: Waypoint[] = [
name: 'South_West_station',
secondaryCode: 'BV',
position: 0,
weight: 100,
},
{
id: 'Mid_West_station',
name: 'Mid_West_station',
secondaryCode: 'BV',
position: 13000000,
weight: 30,
},
{
id: 'Mid_East_station',
name: 'Mid_East_station',
secondaryCode: 'BV',
position: 27550000,
weight: 50,
},
{
id: 'North_East_station',
name: 'North_East_station',
secondaryCode: 'BV',
position: 47050000,
weight: 100,
},
];
1 change: 1 addition & 0 deletions ui-manchette/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type Waypoint = {
position: number; // in mm
name?: string;
secondaryCode?: string;
weight?: number;
};

export type InteractiveWaypoint = Waypoint & {
Expand Down
1 change: 1 addition & 0 deletions ui-speedspacechart/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
],
"exports": {
"./dist/theme.css": "./dist/theme.css",
"./src/components/utils": "./src/components/utils",
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.esm.js"
Expand Down
Loading
Loading