Candlestick chart
Show open, high, low and close per period. A candle that closed at or above its open is green and one that closed lower is red. Candles with a volume add a volume strip underneath.
| Open | High | Low | Close | Volume | |
|---|---|---|---|---|---|
| 1 Sep | $142.00 | $145.40 | $141.00 | $144.40 | 800k |
| 2 Sep | $144.40 | $148.60 | $142.40 | $146.60 | 1.2M |
| 3 Sep | $146.60 | $153.67 | $143.60 | $150.67 | 1.5M |
| 4 Sep | $150.67 | $158.41 | $149.67 | $154.41 | 890k |
| 5 Sep | $154.41 | $155.41 | $149.09 | $151.09 | 1.2M |
| 6 Sep | $151.09 | $153.09 | $145.55 | $148.55 | 1.6M |
| 7 Sep | $148.55 | $151.55 | $145.52 | $146.52 | 980k |
| 8 Sep | $146.52 | $150.52 | $143.14 | $145.14 | 1.3M |
| 9 Sep | $145.14 | $151.52 | $142.14 | $150.52 | 1.7M |
| 10 Sep | $150.52 | $156.24 | $149.52 | $154.24 | 1.1M |
| 11 Sep | $154.24 | $158.23 | $152.24 | $155.23 | 1.4M |
| 12 Sep | $155.23 | $159.77 | $152.23 | $155.77 | 800k |
| 13 Sep | $155.77 | $156.77 | $149.68 | $150.68 | 1.2M |
| 14 Sep | $150.68 | $152.68 | $146.14 | $148.14 | 1.5M |
| 15 Sep | $148.14 | $153.09 | $145.14 | $150.09 | 890k |
| 16 Sep | $150.09 | $155.71 | $149.09 | $151.71 | 1.2M |
| 17 Sep | $151.71 | $158.22 | $149.71 | $157.22 | 1.6M |
| 18 Sep | $157.22 | $161.54 | $154.22 | $159.54 | 980k |
| 19 Sep | $159.54 | $162.54 | $155.36 | $156.36 | 1.3M |
| 20 Sep | $156.36 | $160.36 | $152.74 | $154.74 | 1.7M |
| 21 Sep | $154.74 | $155.74 | $148.28 | $151.28 | 1.1M |
| 22 Sep | $151.28 | $153.28 | $150.11 | $151.11 | 1.4M |
| 23 Sep | $151.11 | $159.65 | $149.11 | $156.65 | 800k |
| 24 Sep | $156.65 | $163.15 | $153.65 | $159.15 | 1.2M |
| 25 Sep | $159.15 | $162.51 | $158.15 | $161.51 | 1.5M |
| 26 Sep | $161.51 | $163.51 | $159.13 | $161.13 | 890k |
| 27 Sep | $161.13 | $164.13 | $152.59 | $155.59 | 1.2M |
| 28 Sep | $155.59 | $159.59 | $153.52 | $154.52 | 1.6M |
| 29 Sep | $154.52 | $156.19 | $152.52 | $155.19 | 980k |
| 30 Sep | $155.19 | $159.39 | $152.19 | $157.39 | 1.3M |
Usage
use hydroxy_leptos::candlestick_chart::{Annotation, Candle, CandlestickChart};
use leptos::prelude::*;
#[component]
pub fn Demo() -> impl IntoView {
// A 30-day run of daily prices with volume, from a deterministic wobble.
let mut price = 142.0;
let mut candles = Vec::new();
let mut labels = Vec::new();
for i in 0..30 {
let t = f64::from(i);
let open = price;
let close = open + (t * 0.9).sin() * 4.0 + (t * 2.3).cos() * 2.0 + 0.4;
let high = open.max(close) + 1.0 + f64::from(i % 4);
let low = open.min(close) - 1.0 - f64::from(i % 3);
let volume = 800_000.0 + f64::from((i * 37) % 11) * 90_000.0;
candles.push(Candle::new(open, high, low, close).with_volume(volume));
labels.push(format!("{} Sep", i + 1));
price = close;
}
// A resistance level and the earnings week, by candle index.
let levels = vec![Annotation::y_line(150.0, "Resistance"), Annotation::x_band(9.0, 13.0, "Earnings")];
view! {
// Hover, or focus the plot and press Left/Right, to read one day.
// Scroll or pinch to zoom, drag to pan, or press + and − on the focused plot.
<CandlestickChart
candles=candles
labels=labels
label="ACME daily prices"
format=|v: f64| format!("${v:.2}")
annotations=levels
zoom=true
/>
}
}use dioxus::prelude::*;
use hydroxy_dioxus::candlestick_chart::{Annotation, Candle, CandlestickChart};
#[component]
pub fn CandlestickChartDemo() -> Element {
// A 30-day run of daily prices with volume, from a deterministic wobble.
let mut price = 142.0;
let mut candles = Vec::new();
let mut labels = Vec::new();
for i in 0..30 {
let t = f64::from(i);
let open = price;
let close = open + (t * 0.9).sin() * 4.0 + (t * 2.3).cos() * 2.0 + 0.4;
let high = open.max(close) + 1.0 + f64::from(i % 4);
let low = open.min(close) - 1.0 - f64::from(i % 3);
let volume = 800_000.0 + f64::from((i * 37) % 11) * 90_000.0;
candles.push(Candle::new(open, high, low, close).with_volume(volume));
labels.push(format!("{} Sep", i + 1));
price = close;
}
// A resistance level and the earnings week, by candle index.
let levels = vec![Annotation::y_line(150.0, "Resistance"), Annotation::x_band(9.0, 13.0, "Earnings")];
rsx! {
// Scroll or pinch to zoom, drag to pan, or press + and − on the focused plot.
CandlestickChart {
candles,
labels,
label: "ACME daily prices",
format: move |v: f64| format!("${v:.2}"),
annotations: levels,
zoom: true,
}
}
}
Anatomy
| Component | data-part | Renders |
|---|---|---|
CandlestickChart | root | figure with a screen-reader table of every candle |
| columns | Focusable plot that drives the readout |
| wick | Thin line from the low to the high |
| body | Open to close; colour comes from the direction |
| tooltip | Open, high, low, close and volume of the active candle |
| volume | Optional strip of volume bars, tinted like their candles |
| crosshair | Dashed rule at the active candle's close, with its price in the gutter |
| annotation | Reference line, band or labelled point; x is a candle index |
| zoom-reset | "Reset zoom" button, shown while zoomed |
Keyboard
| Key | Does |
|---|---|
ArrowLeft / ArrowRight | Move to the previous or next candle |
Home / End | Jump to the first or last candle |
Escape | Hide the readout |
+ / - | With zoom: zoom in or out around the middle |
Shift + ArrowLeft / ArrowRight | With zoom: pan |
0 | With zoom: reset |
Props
| Prop | Type | Notes |
|---|---|---|
candles | Vec<Candle> | Required. Candle::new(open, high, low, close), optionally .with_volume(v) |
labels | Vec<String> | Required. One label per candle |
label | String | Required. What the chart shows; the accessible name |
height | u16 | Price plot height in px. Default 260 |
volume | bool | Show the volume strip when candles have volumes. Default true |
format | Fn(f64) -> String | Formats prices |
annotations | Vec<Annotation> | Reference lines, bands and labelled points; x is a candle index, y a price |
scale | ScaleKind | Linear (default), Log or Symlog price axis |
zoom | bool | Wheel or pinch to zoom, drag to pan, + / - and Shift+arrows on the focused plot. The price axis refits |
Events
| Prop | Type | Notes |
|---|---|---|
on_hover | Callback<Option<Datum>> | The mark under the pointer or keyboard focus changes, or is left. Fires only on a change |
on_select | Callback<Datum> | Click, tap or Enter on a mark |
view | Signal<View> | Controlled zoom window; share one signal to link charts. Uncontrolled when left off |
on_view_change | Callback<View> | Called once a zoom, pan or reset settles; not for changes that came from `view` |