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

ui-chart: spacetimechart: bordered path layer #962

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
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
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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this is unused

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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the - border.offset / 2 here? It seems like the spacing on the right is smaller than offset with this adjustment.

} else {
ctx.lineTo(x, y);
}
});
ctx.stroke();
};

drawSegments(totalPathWidth + borderWidth * 2);

if (border.backgroundColor) {
drawSegments(totalPathWidth, border.backgroundColor);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit confusing: when there is no background color, I would've expected a thin width-sized border offset away from the path. However a thick path is painted instead:

out

}

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

const drawAll = useCallback<DrawingFunction>(
(ctx, stcContext) => {
if (border !== undefined) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: no need for an if here, since we already have one inside the function.

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 @@

// 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
Loading