Skip to content

[charts-premium] Allow color customization in Candlestick chart#21838

Merged
JCQuintas merged 20 commits intomui:masterfrom
JCQuintas:color-candlesticks
Mar 31, 2026
Merged

[charts-premium] Allow color customization in Candlestick chart#21838
JCQuintas merged 20 commits intomui:masterfrom
JCQuintas:color-candlesticks

Conversation

@JCQuintas
Copy link
Copy Markdown
Member

@JCQuintas JCQuintas commented Mar 24, 2026

Summary

  • Add upColor and downColor properties to the candlestick series type for customizing candle body colors
  • Add a default candlestickPalette with green/red colors for bullish/bearish candles (with light/dark mode support)
  • Use the color processor in getColor.ts so tooltip, legend, and WebGL rendering share the same color logic
  • Simplify useCandlestickPlotData by reusing the color processor instead of duplicating color logic
  • Add ColorCandlestick demo with documentation

Closes #21835

…tomization

- Add candlestickPalette with MUI success/error colors as defaults
- Set default colorGetter in getSeriesWithDefaultValues using palette colors
- Simplify getColor processor and useCandlestickPlotData to use colorGetter
- Add ColorCandlestick and ColorGetterCandlestick demos
@mui-bot
Copy link
Copy Markdown

mui-bot commented Mar 24, 2026

Deploy preview: https://deploy-preview-21838--material-ui-x.netlify.app/

Updated pages:

Bundle size report

Bundle Parsed size Gzip size
@mui/x-data-grid 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-pro 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-premium 0B(0.00%) 0B(0.00%)
@mui/x-charts 🔺+26B(+0.01%) 🔺+7B(+0.01%)
@mui/x-charts-pro 🔺+26B(+0.01%) 🔺+8B(+0.01%)
@mui/x-charts-premium 🔺+245B(+0.05%) 🔺+136B(+0.09%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) 0B(0.00%)

Details of bundle changes

Generated by 🚫 dangerJS against c17391a

@JCQuintas JCQuintas self-assigned this Mar 24, 2026
@JCQuintas JCQuintas changed the title [charts] Allow color customization in Candlestick chart [charts-premium] Allow color customization in Candlestick chart Mar 24, 2026
@JCQuintas JCQuintas added plan: Premium Impact at least one Premium user. scope: charts Changes related to the charts. new feature labels Mar 24, 2026
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Mar 24, 2026

Merging this PR will not alter performance

✅ 14 untouched benchmarks


Comparing JCQuintas:color-candlesticks (c17391a) with master (77be213)1

Open in CodSpeed

Footnotes

  1. No successful run was found on master (e56abc3) during the generation of this report, so 77be213 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@JCQuintas JCQuintas added type: new feature Expand the scope of the product to solve a new problem. and removed new feature labels Mar 24, 2026

### Color

The `colors` prop accepts an array where the first value is used for bullish candles (close ≥ open) and the second for bearish candles (close < open).
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any specific reason to use an array instead of named properties for the colors?

The API from tradingview looks more friendly. Maybe with only upColor and downColor to start

https://tradingview.github.io/lightweight-charts/docs/api/interfaces/CandlestickStyleOptions

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It used bullishColor/bearishColor previously, but it felt like parting away from the colors property.

Both work though, it was just preference.

  /**
   * The color of the candle body when the close price is greater than or equal to the open price (bullish).
   * Falls back to the first color from the `colors` palette.
   */
  bullishColor?: string;
  /**
   * The color of the candle body when the close price is less than the open price (bearish).
   * Falls back to the second color from the `colors` palette.
   */
  bearishColor?: string;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It used bullishColor/bearishColor

Yes but in an internal only

Both work though, it was just preference.

Not exactly. The named colors can be refined. The array will be harder.

For now it works because we only have up and down. But with more customization, it will lead to poor DX.

Probably something like: The 2 first colors are for up and down, and the 2 seconds are up and down but only for the wick.

A new joiner on the project seeing this array of colors will have a WTF moment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way about naming, I prefer up/down to bullish/bearish. Every body get it without having to have some financial background

Comment thread packages/x-charts-premium/src/colorPalettes/complementary/candlestick.ts Outdated
@alexfauquette alexfauquette self-requested a review March 25, 2026 10:10
Comment on lines +64 to +69
const paletteColors = React.useMemo(() => {
if (!colors) {
return null;
}
return typeof colors === 'function' ? colors(theme.palette.mode) : colors;
}, [colors, theme.palette.mode]);
Copy link
Copy Markdown
Member

@alexfauquette alexfauquette Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not work with composition.

Since we only have one candle stick series, what about having in series

colors: Colors | (mode: 'light'|'dark') => Colors with type Colors = { up: string; down: string; upWick?: string; downWick?: string }

With that, no need to document the colorGetter that looks over complicated compared to the potential use-cases

@JCQuintas JCQuintas requested a review from alexfauquette March 26, 2026 16:59
Comment on lines +1 to +7
import { type ChartsColorPaletteCallback } from '@mui/x-charts/colorPalettes';

export const candlestickPaletteLight = ['#2e7d32', '#d32f2f'];
export const candlestickPaletteDark = ['#66bb6a', '#f44336'];

export const candlestickPalette: ChartsColorPaletteCallback = (mode) =>
mode === 'dark' ? candlestickPaletteDark : candlestickPaletteLight;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

knip would fail this file telling that palette light is the only one used

Suggested change
import { type ChartsColorPaletteCallback } from '@mui/x-charts/colorPalettes';
export const candlestickPaletteLight = ['#2e7d32', '#d32f2f'];
export const candlestickPaletteDark = ['#66bb6a', '#f44336'];
export const candlestickPalette: ChartsColorPaletteCallback = (mode) =>
mode === 'dark' ? candlestickPaletteDark : candlestickPaletteLight;
export const candlestickPaletteLight = ['#2e7d32', '#d32f2f'];

label?: string | ((location: 'tooltip' | 'legend') => string);
/**
* The color of the candle body when the close price is greater than or equal to the open price.
* @default Candlestick palette up color
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either we hardcode the color or pass allow upColor to be a callback

Suggested change
* @default Candlestick palette up color
* @default "#2e7d32"

Comment on lines +12 to +13
upColor: seriesData.upColor ?? colors[0],
downColor: seriesData.downColor ?? colors[1],
Copy link
Copy Markdown
Member

@alexfauquette alexfauquette Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's because you try to reuse the colors props from the notion of palette.

Image

I was writing a long explanation about solution, but it's easier to add a commit :)
Feel free to remove it if it's causing issues or if you disagree with the proposed API

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My proposal is to have upColor and downColor accept a callback, but after processing those color are only string

The issue with having a centralised place for theming is the composition:

  • You can't reuse colors because it will conflict with the color palette for other series
  • Creating a dedicated props in the DataProvider for a single type of series feels weird

@JCQuintas JCQuintas merged commit 3b0de35 into mui:master Mar 31, 2026
22 checks passed
@JCQuintas JCQuintas deleted the color-candlesticks branch March 31, 2026 15:37
arminmeh pushed a commit to arminmeh/mui-x that referenced this pull request Apr 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plan: Premium Impact at least one Premium user. scope: charts Changes related to the charts. type: new feature Expand the scope of the product to solve a new problem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[charts-premium] Allow color customization in Candlestick chart

3 participants