-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(dataviz): add Linear components (#757)
- Loading branch information
1 parent
612c499
commit e358979
Showing
18 changed files
with
536 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
import React from 'react'; | ||
import { LinearScale } from './LinearScale'; | ||
import { LinearUnits } from '../LinearUnits'; | ||
import { LinearUnitLabel } from '../LinearUnitLabel'; | ||
|
||
const meta: Meta<typeof LinearScale> = { | ||
title: 'LinearScale', | ||
component: LinearScale, | ||
decorators: (Story) => ( | ||
<svg viewBox="0 0 200 200" width="200" height="200"> | ||
<Story /> | ||
</svg> | ||
), | ||
argTypes: { | ||
valueMin: { | ||
control: { | ||
type: 'range', | ||
min: 0, | ||
max: 100, | ||
step: 1, | ||
}, | ||
}, | ||
valueMax: { | ||
control: { | ||
type: 'range', | ||
min: 0, | ||
max: 100, | ||
step: 1, | ||
}, | ||
}, | ||
lengthMin: { | ||
control: { | ||
type: 'range', | ||
min: 0, | ||
max: 200, | ||
step: 1, | ||
}, | ||
}, | ||
lengthMax: { | ||
control: { | ||
type: 'range', | ||
min: 0, | ||
max: 200, | ||
step: 1, | ||
}, | ||
}, | ||
}, | ||
args: { | ||
valueMin: 0, | ||
valueMax: 100, | ||
lengthMin: 0, | ||
lengthMax: 200, | ||
children: ( | ||
<LinearUnits> | ||
<LinearUnitLabel at={0}>Label</LinearUnitLabel> | ||
<LinearUnitLabel at={50}>Label</LinearUnitLabel> | ||
<LinearUnitLabel at={100}>Label</LinearUnitLabel> | ||
</LinearUnits> | ||
), | ||
}, | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof LinearScale>; | ||
|
||
export const LengthMaxPartial: Story = { | ||
name: 'lengthMax=100 (partial)', | ||
args: { | ||
lengthMax: 100, | ||
}, | ||
}; | ||
|
||
export const LengthMaxMax: Story = { | ||
name: 'lengthMax=200 (max)', | ||
args: { | ||
lengthMax: 200, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import React from 'react'; | ||
import { LinearScaleChildProps, LinearScaleProps } from './LinearScaleProps'; | ||
|
||
export const LinearScale = (props: LinearScaleProps) => { | ||
const { children, lengthMax, lengthMin, valueMax, valueMin } = props; | ||
|
||
const ctx = { | ||
linearScale: { | ||
lengthMax, | ||
lengthMin, | ||
valueMax, | ||
valueMin, | ||
}, | ||
}; | ||
|
||
return React.Children.map(children, (child) => { | ||
if (React.isValidElement<LinearScaleChildProps>(child)) { | ||
return React.cloneElement(child, { | ||
ctx: child.props.ctx ?? ctx, | ||
}); | ||
} | ||
|
||
return child; | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import React from 'react'; | ||
import { LinearScaleParams } from '../utils/linear-scale'; | ||
import { LinearCtx, WithCtx } from '../utils'; | ||
|
||
export interface LinearScaleProps extends LinearScaleParams { | ||
children?: React.ReactNode; | ||
} | ||
|
||
export type LinearScaleChildProps = WithCtx<Pick<LinearCtx, 'linearScale'>>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './LinearScale'; | ||
export * from './LinearScaleProps'; |
90 changes: 90 additions & 0 deletions
90
packages/dataviz/src/LinearUnitLabel/LinearUnitLabel.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
import React from 'react'; | ||
import { LinearUnitLabel } from './LinearUnitLabel'; | ||
|
||
const meta: Meta<typeof LinearUnitLabel> = { | ||
title: 'LinearUnitLabel', | ||
component: LinearUnitLabel, | ||
decorators: (Story) => ( | ||
<svg viewBox="0 0 200 200" width="200" height="200"> | ||
<Story /> | ||
</svg> | ||
), | ||
argTypes: { | ||
at: { | ||
control: { | ||
type: 'range', | ||
min: 0, | ||
max: 100, | ||
step: 1, | ||
}, | ||
}, | ||
dominantBaseline: { | ||
control: { type: 'select' }, | ||
options: [ | ||
'text-before-edge', | ||
'text-after-edge', | ||
'middle', | ||
'hanging', | ||
'alphabetic', | ||
'auto', | ||
], | ||
}, | ||
offset: { | ||
control: { type: 'range', min: -20, max: 20, step: 1 }, | ||
}, | ||
}, | ||
args: { | ||
children: <>Label</>, | ||
ctx: { | ||
linearScale: { | ||
valueMin: 0, | ||
valueMax: 100, | ||
lengthMin: 0, | ||
lengthMax: 200, | ||
}, | ||
linearUnits: {}, | ||
}, | ||
}, | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof LinearUnitLabel>; | ||
|
||
export const AtMin: Story = { | ||
name: 'at=(min)', | ||
args: { | ||
at: 0, | ||
}, | ||
}; | ||
|
||
export const AtMid: Story = { | ||
name: 'at=(mid)', | ||
args: { | ||
at: 50, | ||
}, | ||
}; | ||
|
||
export const AtMax: Story = { | ||
name: 'at=(max)', | ||
args: { | ||
at: 100, | ||
}, | ||
}; | ||
|
||
export const Offset4: Story = { | ||
name: 'offset=4 at=..', | ||
args: { | ||
at: 0, | ||
offset: 4, | ||
}, | ||
}; | ||
|
||
export const OffsetNeg4: Story = { | ||
name: 'offset=-4 at=..', | ||
args: { | ||
at: 0, | ||
offset: -4, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import React from 'react'; | ||
import { | ||
LinearUnitLabelElement, | ||
LinearUnitLabelProps, | ||
} from './LinearUnitLabelProps'; | ||
import { drawLinearUnitLabel, mergeCtxOverrides } from '../utils'; | ||
|
||
export const LinearUnitLabel = React.forwardRef< | ||
LinearUnitLabelElement, | ||
LinearUnitLabelProps | ||
>(function LinearUnitLabel(props, ref) { | ||
const { | ||
at, | ||
dominantBaseline: dominantBaselineProp, | ||
offset, | ||
ctx: ctxProp, | ||
overrides, | ||
...other | ||
} = props; | ||
|
||
if (ctxProp === undefined) { | ||
throw Error( | ||
'Oops! `LinearUnits` received `ctx: undefined`. Did you mean to either (1) render as a child of `LinearScale`? or (2) specify `ctx` explicitly?' | ||
); | ||
} | ||
|
||
const ctx = mergeCtxOverrides(ctxProp, overrides); | ||
|
||
const { x, y, textAnchor, dominantBaseline } = drawLinearUnitLabel({ | ||
scale: ctx.linearScale, | ||
units: ctx.linearUnits, | ||
unitLabel: { | ||
at, | ||
dominantBaseline: dominantBaselineProp, | ||
offset, | ||
}, | ||
}); | ||
|
||
return ( | ||
<text | ||
ref={ref} | ||
x={x} | ||
y={y} | ||
textAnchor={textAnchor} | ||
dominantBaseline={dominantBaseline} | ||
{...other} | ||
/> | ||
); | ||
}); |
14 changes: 14 additions & 0 deletions
14
packages/dataviz/src/LinearUnitLabel/LinearUnitLabelProps.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import React from 'react'; | ||
import { LinearCtx, LinearUnitLabelParams, WithOverridableCtx } from '../utils'; | ||
|
||
export interface LinearUnitLabelElement extends SVGTextElement {} | ||
|
||
export interface LinearUnitLabelProps | ||
extends LinearUnitLabelParams, | ||
WithOverridableCtx<Pick<LinearCtx, 'linearScale' | 'linearUnits'>>, | ||
Omit< | ||
React.SVGTextElementAttributes<LinearUnitLabelElement>, | ||
'offset' | 'dominantBaseline' | ||
> { | ||
children?: React.ReactNode; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './LinearUnitLabel'; | ||
export * from './LinearUnitLabelProps'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
import React from 'react'; | ||
import { LinearUnitLabel } from '../LinearUnitLabel'; | ||
import { LinearUnits } from './LinearUnits'; | ||
|
||
const meta: Meta<typeof LinearUnits> = { | ||
title: 'LinearUnits', | ||
component: LinearUnits, | ||
decorators: (Story) => ( | ||
<svg viewBox="0 0 200 200" width="200" height="200"> | ||
<Story /> | ||
</svg> | ||
), | ||
argTypes: { | ||
offset: { | ||
control: { type: 'range', min: -20, max: 20, step: 1 }, | ||
}, | ||
}, | ||
args: { | ||
children: [ | ||
<LinearUnitLabel key="0" at={0}> | ||
Label | ||
</LinearUnitLabel>, | ||
<LinearUnitLabel key="1" at={50}> | ||
Label | ||
</LinearUnitLabel>, | ||
<LinearUnitLabel key="2" at={100}> | ||
Label | ||
</LinearUnitLabel>, | ||
], | ||
ctx: { | ||
linearScale: { | ||
valueMin: 0, | ||
valueMax: 100, | ||
lengthMin: 0, | ||
lengthMax: 200, | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof LinearUnits>; | ||
|
||
export const Default: Story = { | ||
name: '(default)', | ||
args: {}, | ||
}; | ||
|
||
export const Offset4: Story = { | ||
name: 'offset=4', | ||
args: { | ||
offset: 4, | ||
}, | ||
}; | ||
|
||
export const OffsetNeg4: Story = { | ||
name: 'offset=-4', | ||
args: { | ||
offset: -4, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import React from 'react'; | ||
import { LinearUnitsChildProps, LinearUnitsProps } from './LinearUnitsProps'; | ||
import { mergeCtxOverrides } from '../utils'; | ||
|
||
export const LinearUnits = (props: LinearUnitsProps) => { | ||
const { | ||
children, | ||
dy, | ||
dominantBaseline, | ||
offset, | ||
ctx: ctxProp, | ||
overrides, | ||
} = props; | ||
|
||
if (ctxProp === undefined) { | ||
throw Error( | ||
'Oops! `LinearUnits` received `ctx: undefined`. Did you mean to either (1) render as a child of `LinearScale`? or (2) specify `ctx` explicitly?' | ||
); | ||
} | ||
|
||
const ctxWithOverrides = mergeCtxOverrides(ctxProp, overrides); | ||
|
||
const ctx = { | ||
...ctxWithOverrides, | ||
linearUnits: { | ||
dy, | ||
dominantBaseline, | ||
offset, | ||
}, | ||
}; | ||
|
||
return React.Children.map(children, (child) => { | ||
if (React.isValidElement<LinearUnitsChildProps>(child)) { | ||
return React.cloneElement(child, { | ||
ctx: child.props.ctx ?? ctx, | ||
}); | ||
} | ||
|
||
return child; | ||
}); | ||
}; |
Oops, something went wrong.