From 92cad9617b869a992cac156acb9e1b6dbc5216ec Mon Sep 17 00:00:00 2001 From: Valentin Chanas Date: Fri, 14 Feb 2025 15:24:54 +0100 Subject: [PATCH] review changes --- .../{SimpleRect.tsx => CanvasRect.tsx} | 62 ++++------- .../src/components/DottedBorderRect.tsx | 62 +++++++++++ .../src/components/PatternRect.tsx | 4 +- .../src/stories/draw-rectangle.stories.tsx | 7 +- ui-spacetimechart/src/styles/main.css | 101 ------------------ 5 files changed, 90 insertions(+), 146 deletions(-) rename ui-spacetimechart/src/components/{SimpleRect.tsx => CanvasRect.tsx} (50%) create mode 100644 ui-spacetimechart/src/components/DottedBorderRect.tsx diff --git a/ui-spacetimechart/src/components/SimpleRect.tsx b/ui-spacetimechart/src/components/CanvasRect.tsx similarity index 50% rename from ui-spacetimechart/src/components/SimpleRect.tsx rename to ui-spacetimechart/src/components/CanvasRect.tsx index 152a62c06..c43cc4895 100644 --- a/ui-spacetimechart/src/components/SimpleRect.tsx +++ b/ui-spacetimechart/src/components/CanvasRect.tsx @@ -9,26 +9,31 @@ export type FillStyle = | CanvasGradient | ((ctx: CanvasRenderingContext2D) => string | CanvasPattern | CanvasGradient | null); -export type SimpleRectProps = { +export type CanvasRectProps = { timeStart: Date; timeEnd: Date; spaceStart: number; // mm spaceEnd: number; // mm fillStyle: FillStyle; - border?: boolean; + drawBorder?: ( + ctx: CanvasRenderingContext2D, + timeAxis: string, + timePixelSize: number, + spacePixelSize: number + ) => void; }; -export const SimpleRect = ({ +export const CanvasRect = ({ timeStart, timeEnd, spaceStart, spaceEnd, fillStyle, - border, -}: SimpleRectProps) => { + drawBorder, +}: CanvasRectProps) => { const overlayRef = useRef(null); const drawRegion = useCallback( - (ctx, { getSpacePixel, getTimePixel, spaceAxis }) => { + (ctx, { getSpacePixel, getTimePixel, timeAxis }) => { const timeStartPixel = getTimePixel(Number(timeStart)); const endTimePixel = getTimePixel(Number(timeEnd)); const spaceStartPixel = getSpacePixel(spaceStart); @@ -48,46 +53,23 @@ export const SimpleRect = ({ } else { ctx.fillStyle = fillStyle; } - if (spaceAxis === 'x') { - ctx.translate(spaceStartPixel, timeStartPixel); - ctx.fillRect(0, 0, areaSpaceSize, areaTimeSize); - } else { + + if (timeAxis === 'x') { ctx.translate(timeStartPixel, spaceStartPixel); ctx.fillRect(0, 0, areaTimeSize, areaSpaceSize); + } else { + ctx.translate(spaceStartPixel, timeStartPixel); + ctx.fillRect(0, 0, areaSpaceSize, areaTimeSize); } - ctx.restore(); - if (border && overlayRef.current) { - let borderSpaceSize, borderTimeSize, borderSpaceStart, borderTimeStart; - if (areaSpaceSize >= 0) { - borderSpaceSize = areaSpaceSize; - borderSpaceStart = spaceStartPixel; - } else { - borderSpaceSize = -areaSpaceSize; - borderSpaceStart = spaceStartPixel + areaSpaceSize; - } - if (areaTimeSize >= 0) { - borderTimeSize = areaTimeSize; - borderTimeStart = timeStartPixel; - } else { - borderTimeSize = -areaTimeSize; - borderTimeStart = timeStartPixel + areaTimeSize; - } - if (spaceAxis === 'x') { - overlayRef.current.style.left = `${borderSpaceStart}px`; - overlayRef.current.style.top = `${borderTimeStart}px`; - overlayRef.current.style.width = `${borderSpaceSize}px`; - overlayRef.current.style.height = `${borderTimeSize}px`; - } else { - overlayRef.current.style.left = `${borderTimeStart}px`; - overlayRef.current.style.top = `${borderSpaceStart}px`; - overlayRef.current.style.width = `${borderTimeSize}px`; - overlayRef.current.style.height = `${borderSpaceSize}px`; - } + + if (drawBorder) { + drawBorder(ctx, timeAxis, areaTimeSize, areaSpaceSize); } + ctx.restore(); }, - [timeStart, timeEnd, spaceStart, spaceEnd, fillStyle, border] + [timeStart, timeEnd, spaceStart, spaceEnd, fillStyle, drawBorder] ); useDraw('background', drawRegion); - return
; + return null; }; diff --git a/ui-spacetimechart/src/components/DottedBorderRect.tsx b/ui-spacetimechart/src/components/DottedBorderRect.tsx new file mode 100644 index 000000000..d0fb49846 --- /dev/null +++ b/ui-spacetimechart/src/components/DottedBorderRect.tsx @@ -0,0 +1,62 @@ +import React from 'react'; + +import { CanvasRect, type CanvasRectProps } from './CanvasRect'; + +export type DottedBorderRectProps = CanvasRectProps & { + lineWidth: number; + spacing: number; +}; + +/** + * radius 1 black dot with radius 3 white region around it + */ +function squareDot(ctx: CanvasRenderingContext2D, cx: number, cy: number) { + ctx.fillStyle = 'white'; + ctx.fillRect(cx - 1, cy - 1, 3, 3); + ctx.fill(); + + ctx.fillStyle = 'black'; + ctx.fillRect(cx, cy, 1, 1); + ctx.fill(); +} + +export const DottedBorderRect = ({ + timeStart, + timeEnd, + spaceStart, + spaceEnd, + fillStyle, + lineWidth, + spacing, +}: DottedBorderRectProps) => { + const drawBorder = ( + ctx: CanvasRenderingContext2D, + timeAxis: string, + timePixelSize: number, + spacePixelSize: number + ) => { + const width = timeAxis === 'x' ? timePixelSize : spacePixelSize; + const height = timeAxis === 'x' ? spacePixelSize : timePixelSize; + + ctx.lineWidth = lineWidth; + + for (let i = 0; Math.abs(i) < Math.abs(width); i += spacing * Math.sign(width)) { + squareDot(ctx, i, 0); + squareDot(ctx, i, 0 + height); + } + for (let i = 0; Math.abs(i) < Math.abs(height); i += spacing * Math.sign(height)) { + squareDot(ctx, 0, i); + squareDot(ctx, 0 + width, i); + } + }; + return ( + + ); +}; diff --git a/ui-spacetimechart/src/components/PatternRect.tsx b/ui-spacetimechart/src/components/PatternRect.tsx index f9574cecf..0e1499434 100644 --- a/ui-spacetimechart/src/components/PatternRect.tsx +++ b/ui-spacetimechart/src/components/PatternRect.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { SimpleRect } from './SimpleRect'; +import { CanvasRect } from './CanvasRect'; export type PatternRectProps = { timeStart: Date; @@ -25,7 +25,7 @@ export const PatternRect = ({ return pattern; }; return ( - ))} {state.rect && ( - )} diff --git a/ui-spacetimechart/src/styles/main.css b/ui-spacetimechart/src/styles/main.css index b91fb8bb5..cbe4f2de9 100644 --- a/ui-spacetimechart/src/styles/main.css +++ b/ui-spacetimechart/src/styles/main.css @@ -2,10 +2,6 @@ @import 'tailwindcss/components'; @import 'tailwindcss/utilities'; -.space-time-chart { - overflow: hidden; -} - .spacetimechart-tooltip { position: absolute; background-color: rgba(0, 0, 0, 0.85); @@ -50,100 +46,3 @@ text-overflow: ellipsis; } } - -.simple-rect-border-box { - position: relative; - border: none; /* Remove default border */ -} - -.simple-rect-border-box::after { - content: ""; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: - /* TOP BORDER */ - repeating-linear-gradient( - 90deg, - theme('colors.primary.90') 0px, - theme('colors.primary.90') 1px, - transparent 1px, - transparent 4px - ) - top 1px left 1px / 100% 1px no-repeat, - /* RIGHT */ - repeating-linear-gradient( - 0deg, - theme('colors.primary.90') 0px, - theme('colors.primary.90') 1px, - transparent 1px, - transparent 4px - ) - bottom 1px right 1px / 1px 100% no-repeat, - /* BOTTOMĀ BORDER */ - repeating-linear-gradient( - 90deg, - theme('colors.primary.90') 0px, - theme('colors.primary.90') 1px, - transparent 1px, - transparent 4px - ) - bottom 1px left 1px / 100% 1px no-repeat, - /* LEFT BORDER */ - repeating-linear-gradient( - 0deg, - theme('colors.primary.90') 0px, - theme('colors.primary.90') 1px, - transparent 1px, - transparent 4px - ) - left 1px bottom 1px / 1px 100% no-repeat; - content: ""; - pointer-events: none; -} - -.simple-rect-border-box::before { - content: ""; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: - repeating-linear-gradient( - 90deg, - theme('colors.white.100') 0px, - theme('colors.white.100') 3px, - transparent 3px, - transparent 4px - ) - top / 100% 3px no-repeat, - repeating-linear-gradient( - 0deg, - theme('colors.white.100') 0px, - theme('colors.white.100') 3px, - transparent 3px, - transparent 4px - ) - right / 3px 100% no-repeat, - repeating-linear-gradient( - 90deg, - theme('colors.white.100') 0px, - theme('colors.white.100') 3px, - transparent 3px, - transparent 4px - ) - bottom / 100% 3px no-repeat, - repeating-linear-gradient( - 0deg, - theme('colors.white.100') 0px, - theme('colors.white.100') 3px, - transparent 3px, - transparent 4px - ) - left / 3px 100% no-repeat; - content: ""; - pointer-events: none; -}