Candlestick Chart
Financial OHLC visualisation highlighting open, high, low, and close for trading periods.
Source
LLM docs
Package
npm install @plocks/chartsExamples
6
Properties
64
Playground
Basics
Visualizes financial OHLC price movements over time.
Loading demo…
import { CandlestickChart } from '@plocks/charts';
import { PRICE_SERIES } from './data';
export function Demo() {
return (
<CandlestickChart
title="AAPL daily candles"
subtitle="Includes 3 & 5-day moving averages"
h={360}
series={[
{
id: 'apple',
name: 'Apple Inc.',
data: PRICE_SERIES,
colorBull: '#34C38F',
colorBear: '#F56565',
wickColor: '#6B7280',
},
]}
movingAveragePeriods={[3, 5]}
xAxis={{
show: true,
labelFormatter: (value) => new Date(value).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
}),
title: 'Trading day',
}}
yAxis={{
show: true,
title: 'Price (USD)',
labelFormatter: (value) => `$${value.toFixed(0)}`,
}}
grid={{ show: true, color: '#E5EAF7' }}
legend={{ show: true }}
tooltip={{
show: true,
formatter: (candle) =>
`O: $${candle.open.toFixed(2)} • H: $${candle.high.toFixed(2)} • L: $${candle.low.toFixed(2)} • C: $${candle.close.toFixed(2)}`,
}}
enableCrosshair
liveTooltip
animation={{ duration: 400 }}
enablePanZoom
zoomMode="both"
minZoom={0.2}
resetOnDoubleTap
clampToInitialDomain
xScaleType="time"
/>
);
}Battery Material Pricing
Loading demo…
import { CandlestickChart } from '@plocks/charts';
import { LITHIUM_SERIES, NICKEL_SERIES, negotiationMarkers } from './data';
const formatWeek = (value: number) => new Date(value).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
});
export function Demo() {
return (
<CandlestickChart
title="Battery Material Pricing"
subtitle="Negotiation window tracked across lithium and nickel contracts"
h={420}
series={[
{
id: 'lithium',
name: 'Lithium carbonate (USD/ton)',
data: LITHIUM_SERIES,
colorBull: '#0ea5e9',
colorBear: '#bfdbfe',
wickColor: '#1d4ed8',
},
{
id: 'nickel',
name: 'Nickel sulfate (USD/ton)',
data: NICKEL_SERIES,
colorBull: '#facc15',
colorBear: '#fef08a',
wickColor: '#ca8a04',
},
]}
movingAveragePeriods={[3]}
movingAverageColors={['#6366f1']}
annotations={negotiationMarkers}
grid={{ show: true, color: '#E3E8F4' }}
legend={{ show: true }}
tooltip={{
show: true,
formatter: (candle) => `Open $${candle.open.toLocaleString('en-US')} • Close $${candle.close.toLocaleString('en-US')} \nRange $${candle.low.toLocaleString('en-US')} – $${candle.high.toLocaleString('en-US')}`,
}}
xAxis={{
show: true,
title: 'Week of shipment',
labelFormatter: formatWeek,
}}
yAxis={{
show: true,
title: 'Spot price (USD per metric ton)',
labelFormatter: (value) => `$${value.toLocaleString('en-US')}`,
}}
enableCrosshair
liveTooltip
multiTooltip
xScaleType="time"
/>
);
}Cloud Infra Cost Swings
Loading demo…
import { CandlestickChart } from '@plocks/charts';
import { COST_SERIES, CloudCandle, annotations } from './data';
export function Demo() {
return (
<CandlestickChart
title="Cloud Spend Volatility"
subtitle="Optimization window captured a 4.7% cost reduction"
h={420}
series={[
{
id: 'cloud-costs',
name: 'Daily infrastructure cost',
data: COST_SERIES,
colorBull: '#10b981',
colorBear: '#ef4444',
wickColor: '#475569',
},
]}
movingAveragePeriods={[3, 5, 8]}
movingAverageColors={['#38bdf8', '#6366f1', '#f97316']}
showMovingAverages
showVolume
volumeHeightRatio={0.24}
annotations={annotations}
grid={{ show: true, color: '#E3E8F4' }}
legend={{ show: true }}
tooltip={{
show: true,
formatter: (candle) => {
const delta = candle.close - candle.open;
const deltaLabel = `${delta >= 0 ? '+' : ''}$${delta.toLocaleString('en-US', { maximumFractionDigits: 0 })}`;
const note = (candle as CloudCandle).note ? `\n• ${ (candle as CloudCandle).note }` : '';
return [
`Start: $${candle.open.toLocaleString('en-US', { maximumFractionDigits: 0 })}`,
`End: $${candle.close.toLocaleString('en-US', { maximumFractionDigits: 0 })} (${deltaLabel})`,
`Compute hours: ${(candle.volume ?? 0).toLocaleString('en-US')}`,
].join(' • ') + note;
},
}}
xAxis={{
show: true,
title: 'Billing day',
labelFormatter: (value) => new Date(value).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
}),
}}
yAxis={{
show: true,
title: 'Daily cloud cost (USD)',
labelFormatter: (value) => `$${value.toLocaleString('en-US', { maximumFractionDigits: 0 })}`,
}}
enableCrosshair
liveTooltip
xScaleType="time"
/>
);
}Crypto Treasury Balances
Loading demo…
import { CandlestickChart } from '@plocks/charts';
import { TREASURY_SERIES, TreasuryCandle, annotations } from './data';
const formatWeek = (value: number) => new Date(value).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
});
export function Demo() {
return (
<CandlestickChart
title="Crypto Treasury Balances"
subtitle="Weekly BTC position changes with treasury policy markers"
h={420}
series={[
{
id: 'btc',
name: 'BTC holdings (USD equivalent)',
data: TREASURY_SERIES,
colorBull: '#0ea5e9',
colorBear: '#f97316',
wickColor: '#1f2937',
},
]}
movingAveragePeriods={[2, 4, 6]}
movingAverageColors={['#38bdf8', '#6366f1', '#facc15']}
showMovingAverages
showVolume
volumeHeightRatio={0.2}
annotations={annotations}
grid={{ show: true, color: '#E3E8F4' }}
legend={{ show: true }}
tooltip={{
show: true,
formatter: (candle) => {
const delta = candle.close - candle.open;
const deltaLabel = `${delta >= 0 ? '+' : '-'}$${Math.abs(delta).toLocaleString('en-US', { maximumFractionDigits: 0 })}`;
const note = (candle as TreasuryCandle).note ? `\n• ${(candle as TreasuryCandle).note}` : '';
return [
`Open $${candle.open.toLocaleString('en-US', { maximumFractionDigits: 0 })}`,
`Close $${candle.close.toLocaleString('en-US', { maximumFractionDigits: 0 })} (${deltaLabel})`,
`Flow: ${(candle.volume ?? 0).toLocaleString('en-US')} BTC`,
].join(' • ') + note;
},
}}
xAxis={{
show: true,
title: 'Week of',
labelFormatter: formatWeek,
}}
yAxis={{
show: true,
title: 'USD value (thousands)',
labelFormatter: (value) => `$${value.toLocaleString('en-US')}`,
}}
enableCrosshair
liveTooltip
multiTooltip
xScaleType="time"
/>
);
}Saas Usage Peaks
Loading demo…
import { CandlestickChart } from '@plocks/charts';
import { USAGE_SERIES, UsageCandle, annotations } from './data';
const formatDay = (value: number) => new Date(value).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
});
export function Demo() {
return (
<CandlestickChart
title="SaaS Usage Peaks"
subtitle="Daily active sessions during phased launch with capacity guardrails"
h={420}
series={[
{
id: 'active-sessions',
name: 'Concurrent sessions',
data: USAGE_SERIES,
colorBull: '#22c55e',
colorBear: '#ef4444',
wickColor: '#0f172a',
},
]}
movingAveragePeriods={[3, 5]}
movingAverageColors={['#0ea5e9', '#f97316']}
showMovingAverages
showVolume
volumeHeightRatio={0.24}
annotations={annotations}
grid={{ show: true, color: '#E3E8F4' }}
legend={{ show: true }}
tooltip={{
show: true,
formatter: (candle) => {
const delta = candle.close - candle.open;
const deltaLabel = `${delta >= 0 ? '+' : ''}${delta.toLocaleString('en-US')}`;
const note = (candle as UsageCandle).note ? `\n• ${(candle as UsageCandle).note}` : '';
return [
`Start ${candle.open.toLocaleString('en-US')} sessions`,
`End ${candle.close.toLocaleString('en-US')} (${deltaLabel})`,
`Peak ${candle.high.toLocaleString('en-US')} • Floor ${candle.low.toLocaleString('en-US')}`,
`Requests ${(candle.volume ?? 0).toLocaleString('en-US')}`,
].join(' • ') + note;
},
}}
xAxis={{
show: true,
title: 'Day',
labelFormatter: formatDay,
}}
yAxis={{
show: true,
title: 'Concurrent sessions',
labelFormatter: (value) => value.toLocaleString('en-US'),
}}
enableCrosshair
liveTooltip
multiTooltip
xScaleType="time"
/>
);
}Subscription Mrr Dynamics
Loading demo…
import { CandlestickChart } from '@plocks/charts';
import { MRR_SERIES, MrrCandle, annotations } from './data';
const formatMonth = (value: number) => new Date(value).toLocaleDateString('en-US', {
month: 'short',
year: 'numeric',
});
export function Demo() {
return (
<CandlestickChart
title="Subscription MRR Momentum"
subtitle="Expansion revenue outpaced churn across a pricing refresh"
h={420}
series={[
{
id: 'mrr',
name: 'Monthly recurring revenue',
data: MRR_SERIES,
colorBull: '#22c55e',
colorBear: '#ef4444',
wickColor: '#0f172a',
},
]}
movingAveragePeriods={[2, 3]}
movingAverageColors={['#14b8a6', '#6366f1']}
showMovingAverages
showVolume
volumeHeightRatio={0.22}
annotations={annotations}
grid={{ show: true, color: '#E3E8F4' }}
legend={{ show: true }}
tooltip={{
show: true,
formatter: (candle) => {
const net = candle.close - candle.open;
const netLabel = `${net >= 0 ? '+' : '-'}$${Math.abs(net).toLocaleString('en-US')}`;
const note = (candle as MrrCandle).note ? `\n• ${(candle as MrrCandle).note}` : '';
return [
`Open $${candle.open.toLocaleString('en-US')}`,
`Close $${candle.close.toLocaleString('en-US')} (${netLabel})`,
`Net expansions: ${(candle.volume ?? 0).toLocaleString('en-US')} accounts`,
].join(' • ') + note;
},
}}
xAxis={{
show: true,
title: 'Month',
labelFormatter: formatMonth,
}}
yAxis={{
show: true,
title: 'MRR (USD)',
labelFormatter: (value) => `$${value.toLocaleString('en-US')}`,
}}
enableCrosshair
liveTooltip
multiTooltip
xScaleType="time"
/>
);
}Related charts
Further reading
React Native design for iOS, Android, and Web.
Quick Links
Resources