Skip to content

Commit

Permalink
ui-chart: spacetimechart: bordered path layer
Browse files Browse the repository at this point in the history
Co-authored-by: Uriel-Sautron <[email protected]>
Signed-off-by: Math_R_ <[email protected]>
  • Loading branch information
Math-R and Uriel-Sautron committed Mar 7, 2025
1 parent 57effe7 commit b833579
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 4 deletions.
51 changes: 51 additions & 0 deletions ui-charts/src/spaceTimeChart/components/PathLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type PathStyle = {
opacity?: number;
lineCap?: CanvasLineCap;
};

export type PathLevel = 1 | 2 | 3 | 4;
const STYLES: Record<PathLevel, PathStyle> = {
1: {
Expand Down Expand Up @@ -66,6 +67,13 @@ export type PathLayerProps = {
color: string;
pickingTolerance?: number;
level?: PathLevel;
border?: {
offset: number;
level: PathLevel;
color: string;
width?: number;
backgroundColor?: string;
};
};

/**
Expand All @@ -79,6 +87,7 @@ export const PathLayer = ({
color,
level = DEFAULT_LEVEL,
pickingTolerance = DEFAULT_PICKING_TOLERANCE,
border,
}: PathLayerProps) => {
/**
* This function returns the list of points to join to draw the path. It will be both used to
Expand Down Expand Up @@ -336,8 +345,48 @@ export const PathLayer = ({
[path]
);

const drawBorder = useCallback<DrawingFunction>(
(ctx, stcContext) => {
if (!border) return;
const borderWidth = border.width || 1;
const mainPathStyle = STYLES[level];
const totalPathWidth = border.offset * 2 + mainPathStyle.width;

const segments = getPathSegments(stcContext);
ctx.save();
const drawSegments = (lineWidth: number, borderColor = border.color) => {
ctx.strokeStyle = borderColor;
ctx.lineWidth = lineWidth;
ctx.beginPath();
segments.forEach(({ x, y }, i) => {
if (x === segments[i - 1]?.x && y === segments[i - 1]?.y) return;
if (i === 0) {
ctx.moveTo(x, y);
} else if (i === segments.length - 1) {
ctx.lineTo(x - border.offset / 2, y);
} else {
ctx.lineTo(x, y);
}
});
ctx.stroke();
};

drawSegments(totalPathWidth + borderWidth * 2);

if (border.backgroundColor) {
drawSegments(totalPathWidth, border.backgroundColor);
}

ctx.restore();
},
[border, getPathSegments, level]
);

const drawAll = useCallback<DrawingFunction>(
(ctx, stcContext) => {
if (border !== undefined) {
drawBorder(ctx, stcContext);
}
// Draw stops:
ctx.strokeStyle = color;
ctx.lineWidth = PAUSE_THICKNESS;
Expand Down Expand Up @@ -383,6 +432,8 @@ export const PathLayer = ({
drawExtremities,
computePathLength,
drawLabel,
drawBorder,
border,
path.label,
]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const CLOSED_DOORS = [
},
];

const DEFAULT_PATH_LEVEL = 2;

type MonoTrackSpaceProps = {
from: number;
to: number;
Expand Down Expand Up @@ -257,7 +259,13 @@ const Wrapper = ({ swapAxis, spaceScaleType }: WrapperProps) => {
}}
>
{PATHS.map((path) => (
<PathLayer key={path.id} path={path} color={path.color} />
<PathLayer
key={path.id}
path={path}
color={path.color}
border={path.border}
level={path.level || DEFAULT_PATH_LEVEL}
/>
))}
{MONO_TRACK_SPACES.map(({ from, to }, i) => (
<MonoTrackSpace key={i} from={from} to={to} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,13 @@ const Wrapper = ({
yOffset={yOffset}
>
{paths.map((path) => (
<PathLayer key={path.id} path={path} color={path.color} />
<PathLayer
key={path.id}
path={path}
color={path.color}
border={path.border}
level={path.level || 2}
/>
))}
</SpaceTimeChart>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,13 @@ const Wrapper = ({ color1, color2, color3, spaceScaleType }: WrapperProps) => {
}}
>
{PATHS.map((path) => (
<PathLayer key={path.id} path={path} color={path.color} />
<PathLayer
key={path.id}
path={path}
color={path.color}
border={path.border}
level={path.level || 2}
/>
))}
</SpaceTimeChart>
</div>
Expand Down
50 changes: 49 additions & 1 deletion ui-charts/src/spaceTimeChart/stories/lib/paths.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { keyBy } from 'lodash';

import type { OperationalPoint, PathData } from '../../lib/types';
import { PathLevel } from '../../components/PathLayer';

Check warning on line 4 in ui-charts/src/spaceTimeChart/stories/lib/paths.ts

View workflow job for this annotation

GitHub Actions / build

`../../components/PathLayer` import should occur before type import of `../../lib/types`

Check warning on line 4 in ui-charts/src/spaceTimeChart/stories/lib/paths.ts

View workflow job for this annotation

GitHub Actions / build

All imports in the declaration are only used as types. Use `import type`

const KM = 1000;
const MIN = 60 * 1000;
Expand Down Expand Up @@ -123,7 +124,54 @@ export const START_DATE = new Date('2024/04/02');

// TODO:
// Store and share the hardcoded colors with other stories that use the GET as well
export const PATHS: (PathData & { color: string })[] = [
export const PATHS: (PathData & {
color: string;
border?: {
offset: number;
level: PathLevel;
color: string;
backgroundColor?: string;
};
level?: PathLevel;
})[] = [
// Paced Train
...getPaths(
'Paced',
OPERATIONAL_POINTS,
3 * MIN,
60 * MIN,
(80 * KM) / (60 * MIN),
2,
+START_DATE + 10 * MIN,
{
color: '#B2539E',
border: {
offset: 3.5,
color: '#B2539E',
level: 2,
backgroundColor: '#FAF2F8',
},
}
),
...getPaths(
'Selected Paced',
OPERATIONAL_POINTS,
3 * MIN,
60 * MIN,
(80 * KM) / (60 * MIN),
1,
+START_DATE + 40 * MIN,
{
color: '#B2539E',
level: 1,
border: {
offset: 4,
color: 'transparent',
level: 2,
backgroundColor: '#FAE6F6',
},
}
),
// Omnibuses:
...getPaths(
'omnibus',
Expand Down

0 comments on commit b833579

Please sign in to comment.