Getting Started
Charts
- Charts
- Line Chart
- Bar Chart
- Area Chart
- Scatter Chart
- Pie Chart
- Donut Chart
- Dot Plot Chart
- Lollipop Chart
- Dumbbell Chart
- Slope Chart
- Range Chart
- Histogram Chart
- Box Plot Chart
- Violin Chart
- Polar Chart
- Parallel Coordinates
- SPLOM Chart
- Parcats Chart
- Candlestick Chart
- OHLC Chart
- Waterfall Chart
- Funnel Chart
- Heatmap Chart
- Contour Chart
- Density Chart
- Ternary Chart
- Radar Chart
- Treemap Chart
- Sunburst Chart
- Sankey Chart
- Gauge Chart
- Bullet Chart
- Icicle Chart
- Network Graph
- Dendrogram
- Choropleth Chart
"use client"
import { CandlestickChart } from "@/components/ui/charts"
// Stock price data for March-April
const chartData = [
{ date: "2024-03-01", open: 35, high: 45, low: 32, close: 44 },
{ date: "2024-03-04", open: 44, high: 42, low: 35, close: 38 },
{ date: "2024-03-05", open: 38, high: 40, low: 32, close: 37 },
{ date: "2024-03-06", open: 37, high: 25, low: 18, close: 20 },
{ date: "2024-03-07", open: 20, high: 22, low: 8, close: 10 },
{ date: "2024-03-08", open: 10, high: 22, low: 8, close: 20 },
{ date: "2024-03-11", open: 20, high: 22, low: 15, close: 18 },
{ date: "2024-03-12", open: 18, high: 45, low: 16, close: 41 },
{ date: "2024-03-13", open: 41, high: 56, low: 38, close: 54 },
{ date: "2024-03-14", open: 54, high: 42, low: 38, close: 40 },
{ date: "2024-03-15", open: 40, high: 68, low: 38, close: 65 },
{ date: "2024-03-18", open: 65, high: 68, low: 55, close: 66 },
{ date: "2024-03-19", open: 66, high: 45, low: 38, close: 40 },
{ date: "2024-03-20", open: 40, high: 42, low: 28, close: 37 },
{ date: "2024-03-21", open: 37, high: 35, low: 25, close: 30 },
{ date: "2024-03-22", open: 30, high: 32, low: 22, close: 25 },
{ date: "2024-03-25", open: 25, high: 28, low: 18, close: 22 },
{ date: "2024-03-26", open: 22, high: 25, low: 8, close: 10 },
{ date: "2024-03-27", open: 10, high: 22, low: 5, close: 17 },
{ date: "2024-03-28", open: 17, high: 25, low: 12, close: 23 },
{ date: "2024-03-29", open: 23, high: 35, low: 20, close: 32 },
{ date: "2024-04-01", open: 32, high: 48, low: 30, close: 46 },
{ date: "2024-04-02", open: 46, high: 42, low: 38, close: 40 },
{ date: "2024-04-03", open: 40, high: 50, low: 32, close: 48 },
{ date: "2024-04-04", open: 48, high: 50, low: 42, close: 46 },
{ date: "2024-04-05", open: 46, high: 60, low: 44, close: 58 },
{ date: "2024-04-08", open: 58, high: 62, low: 55, close: 60 },
{ date: "2024-04-09", open: 60, high: 50, low: 45, close: 47 },
{ date: "2024-04-10", open: 47, high: 45, low: 38, close: 40 },
{ date: "2024-04-11", open: 40, high: 42, low: 35, close: 38 },
{ date: "2024-04-12", open: 38, high: 40, low: 32, close: 35 },
{ date: "2024-04-15", open: 35, high: 38, low: 30, close: 34 },
{ date: "2024-04-16", open: 34, high: 38, low: 28, close: 33 },
{ date: "2024-04-17", open: 33, high: 35, low: 28, close: 30 },
{ date: "2024-04-18", open: 30, high: 35, low: 25, close: 28 },
{ date: "2024-04-19", open: 28, high: 25, low: 15, close: 18 },
{ date: "2024-04-22", open: 18, high: 22, low: 12, close: 20 },
{ date: "2024-04-23", open: 20, high: 15, low: 5, close: 8 },
{ date: "2024-04-24", open: 8, high: 18, low: 5, close: 15 },
{ date: "2024-04-25", open: 15, high: 32, low: 12, close: 28 },
{ date: "2024-04-26", open: 28, high: 30, low: 20, close: 22 },
{ date: "2024-04-29", open: 22, high: 35, low: 20, close: 32 },
{ date: "2024-04-30", open: 32, high: 58, low: 28, close: 55 },
{ date: "2024-05-01", open: 55, high: 58, low: 48, close: 51 },
{ date: "2024-05-02", open: 51, high: 75, low: 48, close: 72 },
{ date: "2024-05-03", open: 72, high: 85, low: 70, close: 83 },
{ date: "2024-05-06", open: 83, high: 78, low: 70, close: 73 },
{ date: "2024-05-07", open: 73, high: 80, low: 72, close: 75 },
]
export function CandlestickChartDemo() {
return (
<CandlestickChart
data={chartData}
upColor="#22c55e"
downColor="#ef4444"
showGrid
aspectRatio={2.5}
/>
)
}
About
The Candlestick Chart is a financial charting component used to display price movements over time. Each candlestick shows:
- Open - The opening price for the period
- High - The highest price during the period
- Low - The lowest price during the period
- Close - The closing price for the period
- Color - Green for bullish (close > open), Red for bearish (close < open)
Installation
pnpm dlx shadcn@latest add https://ui.simplifying.ai/r/candlestick-chart.json
Usage
import { CandlestickChart } from "@/components/ui/charts"
const data = [
{ date: "2024-03-01", open: 100, high: 110, low: 95, close: 108 },
{ date: "2024-03-02", open: 108, high: 115, low: 105, close: 103 },
{ date: "2024-03-03", open: 103, high: 120, low: 100, close: 118 },
]
export function MyChart() {
return <CandlestickChart data={data} />
}Examples
Default
The default candlestick chart displays filled candles with green for bullish days and red for bearish days.
"use client"
import { CandlestickChart } from "@/components/ui/charts"
// Stock price data for March-April
const chartData = [
{ date: "2024-03-01", open: 35, high: 45, low: 32, close: 44 },
{ date: "2024-03-04", open: 44, high: 42, low: 35, close: 38 },
{ date: "2024-03-05", open: 38, high: 40, low: 32, close: 37 },
{ date: "2024-03-06", open: 37, high: 25, low: 18, close: 20 },
{ date: "2024-03-07", open: 20, high: 22, low: 8, close: 10 },
{ date: "2024-03-08", open: 10, high: 22, low: 8, close: 20 },
{ date: "2024-03-11", open: 20, high: 22, low: 15, close: 18 },
{ date: "2024-03-12", open: 18, high: 45, low: 16, close: 41 },
{ date: "2024-03-13", open: 41, high: 56, low: 38, close: 54 },
{ date: "2024-03-14", open: 54, high: 42, low: 38, close: 40 },
{ date: "2024-03-15", open: 40, high: 68, low: 38, close: 65 },
{ date: "2024-03-18", open: 65, high: 68, low: 55, close: 66 },
{ date: "2024-03-19", open: 66, high: 45, low: 38, close: 40 },
{ date: "2024-03-20", open: 40, high: 42, low: 28, close: 37 },
{ date: "2024-03-21", open: 37, high: 35, low: 25, close: 30 },
{ date: "2024-03-22", open: 30, high: 32, low: 22, close: 25 },
{ date: "2024-03-25", open: 25, high: 28, low: 18, close: 22 },
{ date: "2024-03-26", open: 22, high: 25, low: 8, close: 10 },
{ date: "2024-03-27", open: 10, high: 22, low: 5, close: 17 },
{ date: "2024-03-28", open: 17, high: 25, low: 12, close: 23 },
{ date: "2024-03-29", open: 23, high: 35, low: 20, close: 32 },
{ date: "2024-04-01", open: 32, high: 48, low: 30, close: 46 },
{ date: "2024-04-02", open: 46, high: 42, low: 38, close: 40 },
{ date: "2024-04-03", open: 40, high: 50, low: 32, close: 48 },
{ date: "2024-04-04", open: 48, high: 50, low: 42, close: 46 },
{ date: "2024-04-05", open: 46, high: 60, low: 44, close: 58 },
{ date: "2024-04-08", open: 58, high: 62, low: 55, close: 60 },
{ date: "2024-04-09", open: 60, high: 50, low: 45, close: 47 },
{ date: "2024-04-10", open: 47, high: 45, low: 38, close: 40 },
{ date: "2024-04-11", open: 40, high: 42, low: 35, close: 38 },
{ date: "2024-04-12", open: 38, high: 40, low: 32, close: 35 },
{ date: "2024-04-15", open: 35, high: 38, low: 30, close: 34 },
{ date: "2024-04-16", open: 34, high: 38, low: 28, close: 33 },
{ date: "2024-04-17", open: 33, high: 35, low: 28, close: 30 },
{ date: "2024-04-18", open: 30, high: 35, low: 25, close: 28 },
{ date: "2024-04-19", open: 28, high: 25, low: 15, close: 18 },
{ date: "2024-04-22", open: 18, high: 22, low: 12, close: 20 },
{ date: "2024-04-23", open: 20, high: 15, low: 5, close: 8 },
{ date: "2024-04-24", open: 8, high: 18, low: 5, close: 15 },
{ date: "2024-04-25", open: 15, high: 32, low: 12, close: 28 },
{ date: "2024-04-26", open: 28, high: 30, low: 20, close: 22 },
{ date: "2024-04-29", open: 22, high: 35, low: 20, close: 32 },
{ date: "2024-04-30", open: 32, high: 58, low: 28, close: 55 },
{ date: "2024-05-01", open: 55, high: 58, low: 48, close: 51 },
{ date: "2024-05-02", open: 51, high: 75, low: 48, close: 72 },
{ date: "2024-05-03", open: 72, high: 85, low: 70, close: 83 },
{ date: "2024-05-06", open: 83, high: 78, low: 70, close: 73 },
{ date: "2024-05-07", open: 73, high: 80, low: 72, close: 75 },
]
export function CandlestickChartDemo() {
return (
<CandlestickChart
data={chartData}
upColor="#22c55e"
downColor="#ef4444"
showGrid
aspectRatio={2.5}
/>
)
}
Hollow Candles
Traditional hollow candle style where bullish candles are hollow (outline only) and bearish candles are filled.
"use client"
import { CandlestickChart } from "@/components/ui/charts"
// Stock data for hollow candles demo
const chartData = [
{ date: "2024-03-01", open: 100, high: 108, low: 98, close: 105 },
{ date: "2024-03-04", open: 105, high: 112, low: 102, close: 98 },
{ date: "2024-03-05", open: 98, high: 102, low: 95, close: 100 },
{ date: "2024-03-06", open: 100, high: 115, low: 98, close: 112 },
{ date: "2024-03-07", open: 112, high: 118, low: 110, close: 108 },
{ date: "2024-03-08", open: 108, high: 115, low: 105, close: 113 },
{ date: "2024-03-11", open: 113, high: 120, low: 110, close: 118 },
{ date: "2024-03-12", open: 118, high: 125, low: 115, close: 110 },
{ date: "2024-03-13", open: 110, high: 115, low: 105, close: 112 },
{ date: "2024-03-14", open: 112, high: 128, low: 110, close: 125 },
{ date: "2024-03-15", open: 125, high: 132, low: 122, close: 118 },
{ date: "2024-03-18", open: 118, high: 125, low: 115, close: 122 },
{ date: "2024-03-19", open: 122, high: 135, low: 120, close: 132 },
{ date: "2024-03-20", open: 132, high: 140, low: 130, close: 128 },
{ date: "2024-03-21", open: 128, high: 135, low: 125, close: 133 },
{ date: "2024-03-22", open: 133, high: 142, low: 130, close: 138 },
]
export function CandlestickChartHollowDemo() {
return (
<CandlestickChart
data={chartData}
upColor="#22c55e"
downColor="#ef4444"
showGrid
hollowCandles
aspectRatio={2.5}
/>
)
}
<CandlestickChart data={data} hollowCandles />Scrollable (Large Dataset)
For large datasets with 100+ data points, use a scrollable layout where the y-axis stays fixed while the x-axis scrolls horizontally. This pattern shows the latest data first.
← Scroll horizontally to see more data →
"use client"
import * as React from "react"
import { scaleBand, scaleLinear } from "d3-scale"
import { cn } from "@/lib/utils"
interface CandlestickDataPoint {
date: string
open: number
high: number
low: number
close: number
}
// Large dataset - 100+ trading days
const chartData: CandlestickDataPoint[] = [
{ date: "2024-01-02", open: 45, high: 52, low: 42, close: 50 },
{ date: "2024-01-03", open: 50, high: 55, low: 48, close: 48 },
{ date: "2024-01-04", open: 48, high: 50, low: 40, close: 42 },
{ date: "2024-01-05", open: 42, high: 48, low: 38, close: 46 },
{ date: "2024-01-08", open: 46, high: 52, low: 44, close: 50 },
{ date: "2024-01-09", open: 50, high: 58, low: 48, close: 56 },
{ date: "2024-01-10", open: 56, high: 62, low: 54, close: 58 },
{ date: "2024-01-11", open: 58, high: 60, low: 50, close: 52 },
{ date: "2024-01-12", open: 52, high: 56, low: 48, close: 54 },
{ date: "2024-01-16", open: 54, high: 60, low: 52, close: 58 },
{ date: "2024-01-17", open: 58, high: 65, low: 56, close: 62 },
{ date: "2024-01-18", open: 62, high: 68, low: 60, close: 55 },
{ date: "2024-01-19", open: 55, high: 58, low: 50, close: 52 },
{ date: "2024-01-22", open: 52, high: 55, low: 45, close: 48 },
{ date: "2024-01-23", open: 48, high: 52, low: 42, close: 50 },
{ date: "2024-01-24", open: 50, high: 58, low: 48, close: 56 },
{ date: "2024-01-25", open: 56, high: 62, low: 54, close: 60 },
{ date: "2024-01-26", open: 60, high: 68, low: 58, close: 65 },
{ date: "2024-01-29", open: 65, high: 72, low: 62, close: 70 },
{ date: "2024-01-30", open: 70, high: 75, low: 65, close: 68 },
{ date: "2024-01-31", open: 68, high: 72, low: 60, close: 62 },
{ date: "2024-02-01", open: 62, high: 65, low: 55, close: 58 },
{ date: "2024-02-02", open: 58, high: 62, low: 52, close: 60 },
{ date: "2024-02-05", open: 60, high: 68, low: 58, close: 65 },
{ date: "2024-02-06", open: 65, high: 72, low: 62, close: 70 },
{ date: "2024-02-07", open: 70, high: 78, low: 68, close: 75 },
{ date: "2024-02-08", open: 75, high: 80, low: 70, close: 72 },
{ date: "2024-02-09", open: 72, high: 75, low: 65, close: 68 },
{ date: "2024-02-12", open: 68, high: 72, low: 62, close: 70 },
{ date: "2024-02-13", open: 70, high: 78, low: 68, close: 76 },
{ date: "2024-02-14", open: 76, high: 82, low: 74, close: 80 },
{ date: "2024-02-15", open: 80, high: 85, low: 75, close: 78 },
{ date: "2024-02-16", open: 78, high: 82, low: 72, close: 75 },
{ date: "2024-02-20", open: 75, high: 80, low: 70, close: 78 },
{ date: "2024-02-21", open: 78, high: 85, low: 76, close: 82 },
{ date: "2024-02-22", open: 82, high: 88, low: 80, close: 72 },
{ date: "2024-02-23", open: 72, high: 75, low: 65, close: 68 },
{ date: "2024-02-26", open: 68, high: 72, low: 60, close: 65 },
{ date: "2024-02-27", open: 65, high: 70, low: 58, close: 62 },
{ date: "2024-02-28", open: 62, high: 68, low: 55, close: 58 },
{ date: "2024-02-29", open: 58, high: 62, low: 50, close: 55 },
{ date: "2024-03-01", open: 55, high: 60, low: 48, close: 52 },
{ date: "2024-03-04", open: 52, high: 58, low: 45, close: 56 },
{ date: "2024-03-05", open: 56, high: 65, low: 54, close: 62 },
{ date: "2024-03-06", open: 62, high: 70, low: 60, close: 68 },
{ date: "2024-03-07", open: 68, high: 75, low: 65, close: 72 },
{ date: "2024-03-08", open: 72, high: 78, low: 68, close: 65 },
{ date: "2024-03-11", open: 65, high: 70, low: 58, close: 60 },
{ date: "2024-03-12", open: 60, high: 65, low: 52, close: 58 },
{ date: "2024-03-13", open: 58, high: 65, low: 55, close: 62 },
{ date: "2024-03-14", open: 62, high: 70, low: 60, close: 68 },
{ date: "2024-03-15", open: 68, high: 75, low: 65, close: 55 },
{ date: "2024-03-18", open: 55, high: 58, low: 48, close: 50 },
{ date: "2024-03-19", open: 50, high: 55, low: 42, close: 52 },
{ date: "2024-03-20", open: 52, high: 60, low: 50, close: 58 },
{ date: "2024-03-21", open: 58, high: 65, low: 55, close: 62 },
{ date: "2024-03-22", open: 62, high: 68, low: 58, close: 65 },
{ date: "2024-03-25", open: 65, high: 72, low: 62, close: 70 },
{ date: "2024-03-26", open: 70, high: 78, low: 68, close: 75 },
{ date: "2024-03-27", open: 75, high: 82, low: 72, close: 80 },
{ date: "2024-03-28", open: 80, high: 85, low: 75, close: 78 },
{ date: "2024-04-01", open: 78, high: 82, low: 70, close: 72 },
{ date: "2024-04-02", open: 72, high: 75, low: 65, close: 68 },
{ date: "2024-04-03", open: 68, high: 72, low: 60, close: 70 },
{ date: "2024-04-04", open: 70, high: 78, low: 68, close: 76 },
{ date: "2024-04-05", open: 76, high: 82, low: 74, close: 80 },
{ date: "2024-04-08", open: 80, high: 88, low: 78, close: 85 },
{ date: "2024-04-09", open: 85, high: 92, low: 82, close: 88 },
{ date: "2024-04-10", open: 88, high: 95, low: 85, close: 78 },
{ date: "2024-04-11", open: 78, high: 82, low: 72, close: 75 },
{ date: "2024-04-12", open: 75, high: 80, low: 68, close: 72 },
{ date: "2024-04-15", open: 72, high: 78, low: 65, close: 76 },
{ date: "2024-04-16", open: 76, high: 85, low: 74, close: 82 },
{ date: "2024-04-17", open: 82, high: 90, low: 80, close: 88 },
{ date: "2024-04-18", open: 88, high: 95, low: 85, close: 92 },
{ date: "2024-04-19", open: 92, high: 98, low: 88, close: 85 },
{ date: "2024-04-22", open: 85, high: 88, low: 78, close: 80 },
{ date: "2024-04-23", open: 80, high: 85, low: 72, close: 82 },
{ date: "2024-04-24", open: 82, high: 90, low: 80, close: 88 },
{ date: "2024-04-25", open: 88, high: 95, low: 85, close: 92 },
{ date: "2024-04-26", open: 92, high: 100, low: 90, close: 98 },
]
const upColor = "#22c55e"
const downColor = "#ef4444"
export function CandlestickChartScrollableDemo() {
const scrollRef = React.useRef<HTMLDivElement>(null)
const [hoveredIndex, setHoveredIndex] = React.useState<number | null>(null)
const [tooltipPos, setTooltipPos] = React.useState({ x: 0, y: 0 })
// Fixed dimensions
const height = 320
const margin = { top: 20, right: 20, bottom: 40, left: 0 }
const yAxisWidth = 50
const candleWidth = 12
const candleGap = 4
const chartWidth = chartData.length * (candleWidth + candleGap)
const innerHeight = height - margin.top - margin.bottom
// Y Scale (price) - fixed based on all data
const yScale = React.useMemo(() => {
const allPrices = chartData.flatMap((d) => [d.high, d.low])
const minPrice = Math.min(...allPrices)
const maxPrice = Math.max(...allPrices)
const padding = (maxPrice - minPrice) * 0.1
return scaleLinear()
.domain([Math.max(0, minPrice - padding), maxPrice + padding])
.range([innerHeight, 0])
.nice()
}, [innerHeight])
// X Scale
const xScale = React.useMemo(() => {
return scaleBand()
.domain(chartData.map((d) => d.date))
.range([0, chartWidth])
.padding(0.3)
}, [chartWidth])
const ticks = yScale.ticks(6)
// Get month labels
const monthLabels = React.useMemo(() => {
const labels: { date: string; x: number }[] = []
let lastMonth = -1
chartData.forEach((d) => {
const date = new Date(d.date)
const month = date.getMonth()
if (month !== lastMonth) {
labels.push({
date: d.date,
x: (xScale(d.date) ?? 0) + xScale.bandwidth() / 2,
})
lastMonth = month
}
})
return labels
}, [xScale])
// Scroll to end on mount (show latest data)
React.useEffect(() => {
if (scrollRef.current) {
scrollRef.current.scrollLeft = scrollRef.current.scrollWidth
}
}, [])
return (
<div className="w-full">
<div className="flex">
{/* Fixed Y-Axis */}
<div className="flex-shrink-0" style={{ width: yAxisWidth }}>
<svg width={yAxisWidth} height={height}>
<g transform={`translate(0, ${margin.top})`}>
{ticks.map((tick) => (
<g key={tick}>
<text
x={yAxisWidth - 8}
y={yScale(tick)}
dy="0.32em"
textAnchor="end"
className="fill-muted-foreground text-xs"
>
${tick}
</text>
</g>
))}
</g>
</svg>
</div>
{/* Scrollable Chart Area */}
<div
ref={scrollRef}
className="scrollbar-none flex-1 overflow-x-auto overflow-y-hidden"
style={{
height,
scrollbarWidth: "none",
msOverflowStyle: "none",
}}
>
<div
className="relative"
style={{ width: chartWidth + margin.right, height }}
>
<svg
width={chartWidth + margin.right}
height={height}
className="relative block"
>
<g transform={`translate(0, ${margin.top})`}>
{/* Horizontal Grid Lines */}
{ticks.map((tick) => (
<line
key={`grid-${tick}`}
x1={0}
x2={chartWidth}
y1={yScale(tick)}
y2={yScale(tick)}
stroke="hsl(var(--border))"
strokeDasharray="3 3"
strokeOpacity={0.5}
/>
))}
{/* Vertical Grid Lines */}
{monthLabels.map((label, i) => (
<line
key={`v-${i}`}
x1={label.x}
x2={label.x}
y1={0}
y2={innerHeight}
stroke="hsl(var(--border))"
strokeDasharray="3 3"
strokeOpacity={0.5}
/>
))}
{/* Candlesticks */}
{chartData.map((d, index) => {
const isUp = d.close >= d.open
const color = isUp ? upColor : downColor
const bodyTop = isUp ? d.close : d.open
const bodyBottom = isUp ? d.open : d.close
const x = (xScale(d.date) ?? 0) + xScale.bandwidth() / 2
const isHovered = hoveredIndex === index
return (
<g
key={index}
className={cn(
"cursor-pointer transition-opacity duration-150",
hoveredIndex !== null && !isHovered && "opacity-40"
)}
onMouseEnter={(e) => {
setHoveredIndex(index)
setTooltipPos({ x: e.clientX, y: e.clientY })
}}
onMouseMove={(e) => {
setTooltipPos({ x: e.clientX, y: e.clientY })
}}
onMouseLeave={() => setHoveredIndex(null)}
>
{/* Wick */}
<line
x1={x}
x2={x}
y1={yScale(d.high)}
y2={yScale(d.low)}
stroke={color}
strokeWidth={1}
/>
{/* Body */}
<rect
x={x - candleWidth / 2}
y={yScale(bodyTop)}
width={candleWidth}
height={Math.max(
1,
yScale(bodyBottom) - yScale(bodyTop)
)}
fill={color}
stroke={color}
strokeWidth={1}
rx={1}
/>
</g>
)
})}
{/* X Axis - Month labels */}
<g transform={`translate(0, ${innerHeight})`}>
{monthLabels.map((label, i) => {
const date = new Date(label.date)
return (
<text
key={i}
x={label.x}
y={24}
textAnchor="middle"
className="fill-muted-foreground text-xs"
>
{date.toLocaleDateString("en-US", { month: "short" })}
</text>
)
})}
</g>
</g>
</svg>
</div>
</div>
</div>
{/* Scroll hint */}
<p className="text-muted-foreground mt-2 text-center text-xs">
← Scroll horizontally to see more data →
</p>
{/* Tooltip - Auto-adjusts position based on available space */}
{hoveredIndex !== null &&
(() => {
const tooltipWidth = 140
const tooltipHeight = 120
const padding = 15
// Check viewport bounds
const viewportWidth =
typeof window !== "undefined" ? window.innerWidth : 1000
const viewportHeight =
typeof window !== "undefined" ? window.innerHeight : 800
const showOnLeft =
tooltipPos.x + tooltipWidth + padding > viewportWidth
const showBelow = tooltipPos.y - tooltipHeight - padding < 0
return (
<div
className="pointer-events-none fixed z-50"
style={{
left: showOnLeft
? tooltipPos.x - padding
: tooltipPos.x + padding,
top: showBelow
? tooltipPos.y + padding
: tooltipPos.y - padding,
transform: `translate(${showOnLeft ? "-100%" : "0"}, ${showBelow ? "0" : "-100%"})`,
}}
>
<div className="bg-background rounded-lg border px-3 py-2 shadow-lg">
<p className="text-foreground mb-1 text-sm font-medium">
{new Date(chartData[hoveredIndex].date).toLocaleDateString(
"en-US",
{ month: "short", day: "numeric", year: "numeric" }
)}
</p>
<div className="grid grid-cols-2 gap-x-4 gap-y-0.5 text-sm">
<span className="text-muted-foreground">Open</span>
<span
className="font-mono"
style={{
color:
chartData[hoveredIndex].close >=
chartData[hoveredIndex].open
? upColor
: downColor,
}}
>
${chartData[hoveredIndex].open}
</span>
<span className="text-muted-foreground">High</span>
<span
className="font-mono"
style={{
color:
chartData[hoveredIndex].close >=
chartData[hoveredIndex].open
? upColor
: downColor,
}}
>
${chartData[hoveredIndex].high}
</span>
<span className="text-muted-foreground">Low</span>
<span
className="font-mono"
style={{
color:
chartData[hoveredIndex].close >=
chartData[hoveredIndex].open
? upColor
: downColor,
}}
>
${chartData[hoveredIndex].low}
</span>
<span className="text-muted-foreground">Close</span>
<span
className="font-mono"
style={{
color:
chartData[hoveredIndex].close >=
chartData[hoveredIndex].open
? upColor
: downColor,
}}
>
${chartData[hoveredIndex].close}
</span>
</div>
</div>
</div>
)
})()}
{/* CSS for hiding scrollbar */}
<style jsx>{`
.scrollbar-none::-webkit-scrollbar {
display: none;
}
`}</style>
</div>
)
}
This variant uses a custom implementation with:
- Fixed y-axis on the left
- Horizontally scrollable chart area
- Auto-scrolls to show latest data on load
- Fixed candle width for consistent display
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
data | CandlestickDataPoint[] | required | Array of OHLC data points |
upColor | string | "#22c55e" | Color for bullish (up) candles |
downColor | string | "#ef4444" | Color for bearish (down) candles |
className | string | - | Additional CSS classes |
showGrid | boolean | true | Show dashed grid lines |
showTooltip | boolean | true | Enable tooltip on hover |
hollowCandles | boolean | false | Use hollow style for bullish candles |
aspectRatio | number | 2.5 | Width to height ratio |
valueFormatter | (value: number) => string | $X | Format price values |
dateFormatter | (date: Date) => string | MMM | Format date labels |
Data Types
interface CandlestickDataPoint {
date: string | Date // Trading date
open: number // Opening price
high: number // Highest price
low: number // Lowest price
close: number // Closing price
}Customization
Custom Colors
Use different colors for bullish and bearish candles:
<CandlestickChart
data={data}
upColor="#3b82f6" // Blue for up
downColor="#f97316" // Orange for down
/>Date Formatting
Customize how dates appear on the x-axis:
<CandlestickChart
data={data}
dateFormatter={(date) =>
date.toLocaleDateString("en-US", {
month: "short",
day: "numeric",
})
}
/>Value Formatting
Format the price values in tooltips and y-axis:
<CandlestickChart
data={data}
valueFormatter={(value) => `€${value.toFixed(2)}`}
/>Understanding Candlesticks
- Green/Hollow candle: Bullish - price closed higher than it opened
- Red/Filled candle: Bearish - price closed lower than it opened
- Wick (thin line): Shows the high and low range
- Body (thick rectangle): Shows the open and close range
- Long wick, short body: High volatility, price reversal possible
- Long body, short wick: Strong trend in that direction
Notes
- Candlestick charts are the standard visualization for financial price data and technical analysis
- Each candlestick represents a time period (day, hour, minute) depending on your data granularity
- The hollow candles variant is preferred by many traders as it provides clearer visual distinction
- For large datasets (100+ candles), use the scrollable variant to maintain readability
- Color coding (green/red) helps quickly identify market trends and momentum
- The component supports both Date objects and date strings for flexible data input
- Consider adding volume bars below the candlestick chart for complete market analysis
Deploy and Scale Agents with Simplifying AI
Simplifying AI delivers the infrastructure and developer experience you need to ship reliable audio & agent applications at scale.
Talk to an expert