PayoffChart
StableShows the profit or loss at the end for a position as the price moves, with break-even prices and best and worst outcomes labelled.
Also known as profit loss chart, options payoff
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
A long call
Long call, strike 100
Profit or loss at expiry, dollars per share
You lose at most 5. You break even at 105. Above that the profit keeps growing.
<ChartFrame
title="Long call, strike 100"
subtitle="Profit or loss at expiry, dollars per share"
summary="You lose at most 5. You break even at 105. Above that the profit keeps growing."
table={payoffTable({ legs: LONG_CALL, spotRange: [80, 130] })}
>
<PayoffChart legs={LONG_CALL} spotRange={[80, 130]} spot={98} ariaLabel="Long call, result at expiry" />
</ChartFrame>You pay 5 for the right to buy at 100. The most you lose is what you paid. The profit has no top. The dashed line is today's price.
When to use it
Lets someone see what could happen to a position before they take it, and where it starts to make or lose money.
Made of: Side scale for profit and loss · Zero line · Profit and loss line · Tinted profit area · Hatched loss area · Break-even marks and labels · Max profit and max loss labels · Current price marker · Bottom price labels
Use it for
- An option or a spread: a long call, a bull call spread, an iron condor.
- A share position, alone or combined with options.
- Any result that depends on one price, when you already have the points.
Not for
- A price history over time: use LineChart.
- Open, high, low and close for each day: use CandlestickChart.
- One number with a trend: use StatTile.
Do and avoid
Buy one call at 100
Profit or loss at expiry, in rupees
Buy one call at 100
Profit or loss at expiry, in rupees
Do
- Say "at expiry" and the unit in the ChartFrame subtitle.
- State the break-even prices and the most you can make or lose in the summary.
- Use payoffAtExpiry(legs, spots) when your app needs the same numbers elsewhere.
- Pass the current price as spot so people see where they are now.
Avoid
- Don't use it to promise a result. It shows the end value only, not the chance of reaching it.
- Don't leave out the premium on option legs. The line would show the wrong break-even.
- Don't hide the table view. Some people need the numbers.
On a phone
- The chart measures its container and redraws at that width, so it fills a phone screen.
- Touch or drag across the chart to read the profit or loss at a price. Vertical swipes still scroll the page, and the tooltip stays until you tap elsewhere.
- The tooltip flips to the left of your finger past the middle of the chart.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| points | { spot: number; pnl: number }[] | none | Ready-made points: the price and the profit or loss at that price. Use this or legs. |
| legs | PayoffLeg[] | none | Positions to work the result out from. Each has kind (call, put or stock), side (buy or sell), strike, premium and qty. Used when points is not given. |
| spotRange | [number, number] | none | Price range to draw when working from legs. Defaults to a band around the strikes. |
| steps | number | 120 | Number of steps across the range when working from legs. Every strike is added as an extra point. |
| spot | number | none | Current price. Drawn as a labelled dashed line when it is inside the range. |
| formatValue | (n: number) => string | formatNumber | Formats prices and amounts everywhere in the chart. |
| ariaLabelrequired | string | none | Name for the chart region. |
| height | number | 260 | Plot height in px. Minimum 180. |
| className | string | none | Extra classes on the wrapper. |
"Show code under the preview gives the code for the example on the stage."
States
States this part has beyond its default look. Build each one your screen can reach. States set by a property are in the Code tab.
- focus
- A visible ring appears around the plot when you tab to it. The middle price is chosen at once, with its guide line and pop-up.
- hover
- Moving the pointer over the plot shows the guide line and pop-up for the nearest price. The pop-up hides when the pointer leaves, unless the chart has focus.
- selected price
- Left, Right, PageUp, PageDown, Home and End move to a price. A dot sits on the line and the profit or loss is read out. Escape clears it.
- empty
- With no points and no legs, only the empty axes are drawn.
- price marker hidden
- If spot is outside the range, the current price line and its label are not drawn.
Tokens
Change one of these and every part that uses it follows.
--up-soft--down-soft--up-fg--down-fg--down--chart-1--chart-grid--chart-axis--surface--fg--fg-muted--focus-ring--radius-overlay
Built in
- You can tab to the chart. Left and Right move between prices, PageUp and PageDown jump ten steps, Home and End go to the ends, and Escape clears.
- Each step is read out as the price and then profit, loss or break even with the amount.
- The loss area has a diagonal hatch as well as a tint, so profit and loss do not depend on colour.
- Break-even prices, max profit and max loss are written as text on the chart.
- Unlimited is only said for the right edge, because a price cannot go below zero.
- The pop-up is hidden from screen readers, because the same values are read out as you move.
What you need to do
- Give it an ariaLabel that names the position.
- Put it in a ChartFrame with a summary that states the break-even prices and the most you can make or lose, and pass payoffTable to the table prop.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide