Skip to content

Commit

Permalink
ui-speedspacechart: speed limit tags enhancements
Browse files Browse the repository at this point in the history
- adding logic to make the tooltip follow the cursor move horizontally and vertically
- sticking the tooltip to the chart when the cursor goes outside
- adding logic to prevent text going outside its tag

Signed-off-by: Mathieu <[email protected]>
  • Loading branch information
Mathieu committed Sep 27, 2024
1 parent 4cfb8a7 commit 960c78a
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ const alertFillBlobUrl = createSvgBlobUrl(alertFillSvg);

const RECT_HEIGHT = 17;
const Y_POSITION = 12;
const RECTANGLE_SPACING = 1;
const RECTANGLE_SPACING = 2;
const TEXT_LEFT_PADDING = 4;
const TEXT_RIGHT_PADDING = 8;
const FIRST_TAG_LEFT_PADDING = 8;
const TEXT_RIGHT_PADDING = 4;
const ICON_WIDTH = 16;
const ICON_HEIGHT = 16;
const ICON_OFFSET = 4;
Expand Down Expand Up @@ -85,43 +84,20 @@ export const drawSpeedLimitTags = async ({
let tooltip: tooltipInfos | null = null;

if (speedLimitTags) {
speedLimitTags.forEach(({ position, value }, index) => {
speedLimitTags.forEach(({ position, value }) => {
const { tag, color } = value;
const x = positionOnGraphScale(position.start, maxPosition, width, ratioX, MARGINS);
const nextBoundary = positionOnGraphScale(position.end!, maxPosition, width, ratioX, MARGINS);

if (nextBoundary !== undefined) {
const tagWidth = nextBoundary - x - RECTANGLE_SPACING;

const secondaryColor = COLOR_DICTIONARY[color] || color;

ctx.fillStyle = color;
ctx.strokeStyle = tag === 'UU' ? '#494641' : color;
ctx.lineWidth = 1;

ctx.beginPath();
ctx.fillRect(x, Y_POSITION, tagWidth - RECTANGLE_SPACING, RECT_HEIGHT);

ctx.fillStyle = secondaryColor;

const textWidth =
ctx.measureText(tag).width +
TEXT_RIGHT_PADDING +
(index === 0 ? FIRST_TAG_LEFT_PADDING : 0);

ctx.fillRect(x + 1 + textWidth, Y_POSITION, tagWidth - textWidth - 2, RECT_HEIGHT);
ctx.rect(x + textWidth, Y_POSITION, tagWidth - RECTANGLE_SPACING - textWidth, RECT_HEIGHT);
ctx.strokeRect(x + 1, Y_POSITION, tagWidth - RECTANGLE_SPACING, RECT_HEIGHT);
ctx.closePath();

if (tag === 'UU') {
ctx.lineWidth = 0.5;
ctx.beginPath();
ctx.moveTo(x + textWidth + 2, Y_POSITION);
ctx.lineTo(x + textWidth + 2, Y_POSITION + RECT_HEIGHT);
ctx.closePath();
ctx.stroke();
}
ctx.fillRect(x, Y_POSITION, tagWidth, RECT_HEIGHT);

if (tag === 'incompatible' || tag === 'missing_from_train') {
const image = tag === 'incompatible' ? alertFillImage : questionImage;
Expand Down Expand Up @@ -160,18 +136,62 @@ export const drawSpeedLimitTags = async ({
) {
tooltip = {
cursorX: cursor.x + MARGIN_LEFT,
cursorY: Y_POSITION,
cursorY: cursor.y,
text: 'Incompatible with the infrastructure',
};
}
}
} else {
const actualTextWidth = ctx.measureText(tag).width;

//Take the minimum between the actual text width and the total tag width to prevent the text from overflowing the tag
const textRectWidth = Math.min(
actualTextWidth + TEXT_LEFT_PADDING + TEXT_RIGHT_PADDING,
tagWidth
);

ctx.save();
// Clear the area where the tag text will be drawn
ctx.clearRect(x, Y_POSITION, textRectWidth, RECT_HEIGHT);
ctx.fillStyle = color;
ctx.fillRect(x, Y_POSITION, textRectWidth, RECT_HEIGHT);

ctx.fillStyle = 'white';
ctx.font = '600 12px "IBM Plex Sans"';
ctx.textAlign = 'left';
ctx.textBaseline = 'middle';
const textPosition = x + TEXT_LEFT_PADDING;
ctx.fillText(tag, textPosition, Y_POSITION + TEXT_PADDING_TOP + RECT_HEIGHT / 2);

// Draw the tag text
ctx.fillText(
tag,
textPosition,
Y_POSITION + TEXT_PADDING_TOP + RECT_HEIGHT / 2,
textRectWidth - TEXT_LEFT_PADDING
);

ctx.restore();

const remainingWidth = tagWidth - textRectWidth;

// Fill the remaining width of the tag with the secondary color
ctx.fillStyle = secondaryColor;
ctx.fillRect(
x + textRectWidth + TEXT_RIGHT_PADDING,
Y_POSITION,
remainingWidth,
RECT_HEIGHT
);

ctx.strokeRect(x, Y_POSITION, tagWidth, RECT_HEIGHT);

if (tag === 'UU') {
ctx.lineWidth = 0.5;
ctx.beginPath();
ctx.moveTo(x + textRectWidth, Y_POSITION);
ctx.lineTo(x + textRectWidth, Y_POSITION + RECT_HEIGHT);
ctx.stroke();
}
}
}
});
Expand Down
18 changes: 15 additions & 3 deletions ui-speedspacechart/src/components/layers/SpeedLimitTagsLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,19 @@ type SpeedLimitTagsLayerProps = {
store: Store;
};
const TOOLTIP_HEIGHT = 40;
const MARGIN_ADJUSTMENT = 2;
const LEFT_MARGIN = 52;
const RIGHT_MARGIN = 16;
const TOOLTIP_WIDTH = 238;

const constrainTooltipPosition = (cursorX: number, width: number, tooltipWidth: number) => {
if (cursorX - tooltipWidth / 2 < LEFT_MARGIN) {
return LEFT_MARGIN + tooltipWidth / 2;
}
if (cursorX + tooltipWidth / 2 > width - RIGHT_MARGIN) {
return width - RIGHT_MARGIN - tooltipWidth / 2;
}
return cursorX;
};

const SpeedLimitTagsLayer = ({ width, marginTop, store }: SpeedLimitTagsLayerProps) => {
const canvas = useRef<HTMLCanvasElement>(null);
Expand Down Expand Up @@ -39,8 +51,8 @@ const SpeedLimitTagsLayer = ({ width, marginTop, store }: SpeedLimitTagsLayerPro
/>
{tooltip.current && (
<Tooltip
cursorX={tooltip.current.cursorX}
cursorY={marginTop - TOOLTIP_HEIGHT - MARGIN_ADJUSTMENT}
cursorX={constrainTooltipPosition(tooltip.current.cursorX, width, TOOLTIP_WIDTH)}
cursorY={tooltip.current.cursorY - TOOLTIP_HEIGHT}
height={TOOLTIP_HEIGHT}
text={tooltip.current.text}
/>
Expand Down
12 changes: 8 additions & 4 deletions ui-speedspacechart/src/stories/assets/speed_limit_tags_PMP_LM.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@ export type SpeedLimitTags = {
};

export const speedLimitTags: SpeedLimitTags = {
boundaries: [0, 25000000, 65000000, 95000000, 125000000, 201408607],
boundaries: [0, 5900000, 35915000, 95000000, 125000000, 201408600],
values: [
{ speed_limit_tags_type: 'tag', tag_name: 'MA100', color: '#494641' },
{ speed_limit_tags_type: 'tag', tag_name: 'EVO', color: '#216482' },
{
speed_limit_tags_type: 'tag',
tag_name: 'MA100',
color: '#494641',
},
{ speed_limit_tags_type: 'tag', tag_name: 'incompatible', color: '#EAA72B' },
{
speed_limit_tags_type: 'tag',
tag_name: 'UU',
color: '#D91C1C',
tag_name: 'MA100',
color: '#494641',
},
{ speed_limit_tags_type: 'tag', tag_name: 'missing_from_train', color: '#94918E' },
],
Expand Down

0 comments on commit 960c78a

Please sign in to comment.