Skip to content

Commit 537c51a

Browse files
committed
feat(Chart.Bars): Make it possible to create bar charts
1 parent 07edb05 commit 537c51a

2 files changed

Lines changed: 105 additions & 1 deletion

File tree

src/components/ui/chart/bars.tsx

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { Fragment } from "react/jsx-runtime"
2+
3+
import { cn } from "utils/cn"
4+
5+
import {
6+
chartColor,
7+
ChartFillColor,
8+
ChartStrokeColor,
9+
} from "./fragments/chart-color"
10+
import { Coordinate, useChartContext } from "./fragments/chart-context"
11+
import { Text } from "./fragments/text"
12+
import { createTransition } from "./utils/get-transition"
13+
14+
const { runTransition: runTextTransition } = createTransition({
15+
initStyles: {
16+
translate: "0 -16px",
17+
opacity: "0",
18+
},
19+
targetStyles: {
20+
opacity: "1",
21+
translate: "0 0",
22+
},
23+
})
24+
25+
const { runTransition: runBarTransition } = createTransition({
26+
timingFunction: "bounce",
27+
initStyles: {
28+
transformOrigin: "0 100%",
29+
scale: "1 0",
30+
opacity: "0",
31+
},
32+
targetStyles: {
33+
transformOrigin: "0 100%",
34+
scale: "1 1",
35+
opacity: "1",
36+
},
37+
})
38+
39+
interface BarsProps {
40+
points: Coordinate[]
41+
ground?: number
42+
barWidth?: number
43+
strokeColor?: ChartStrokeColor["color"]
44+
fillColor?: ChartFillColor["color"]
45+
printValue?: (value: Coordinate) => string
46+
}
47+
48+
export const Bars = ({
49+
points,
50+
ground = 8,
51+
barWidth = 16,
52+
strokeColor = "none",
53+
fillColor = "default",
54+
printValue,
55+
}: BarsProps) => {
56+
const { scalePoint, scaleY } = useChartContext()
57+
const bars = points.map(point => {
58+
const top = scalePoint(point)
59+
const bottom = { x: top.x, y: scaleY(ground) }
60+
return { top, bottom, value: point }
61+
})
62+
63+
return (
64+
<>
65+
{bars.map(({ bottom, top, value }, index) => {
66+
const text = printValue?.(value)
67+
return (
68+
<Fragment key={`${top.x}-${top.y}`}>
69+
<rect
70+
ref={node => {
71+
runBarTransition({ node, items: bars.length, index })
72+
}}
73+
rx={2}
74+
ry={2}
75+
x={top.x - barWidth / 2}
76+
y={top.y}
77+
width={barWidth}
78+
height={bottom.y - top.y}
79+
strokeWidth={strokeColor === "none" ? 0 : 1}
80+
className={cn(
81+
chartColor.stroke({ color: strokeColor }),
82+
chartColor.fill({ color: fillColor })
83+
)}
84+
/>
85+
{text && (
86+
<Text
87+
ref={node => {
88+
runTextTransition({ node, items: bars.length, index })
89+
}}
90+
x={top.x}
91+
y={top.y - 8}
92+
anchor="middle"
93+
>
94+
{text}
95+
</Text>
96+
)}
97+
</Fragment>
98+
)
99+
})}
100+
</>
101+
)
102+
}

src/components/ui/chart/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { XAxis, YAxis } from "./axis"
2+
import { Bars } from "./bars"
23
import { Caption } from "./caption"
34
import { ChartRoot } from "./chart-root"
45
import { Dots } from "./dots"
@@ -8,13 +9,14 @@ import { getExtremes } from "./utils/get-extremes"
89

910
export type { Coordinate } from "./fragments/chart-context"
1011

11-
ChartRoot._childrenPriority = [Grid, XAxis, YAxis, Line, Dots]
12+
ChartRoot._childrenPriority = [Grid, XAxis, YAxis, Bars, Line, Dots]
1213

1314
export const Chart = {
1415
Root: ChartRoot,
1516
Grid,
1617
XAxis,
1718
YAxis,
19+
Bars,
1820
Line,
1921
Dots,
2022
Caption,

0 commit comments

Comments
 (0)