-
Notifications
You must be signed in to change notification settings - Fork 12k
Introduce Colors plugin #10764
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Introduce Colors plugin #10764
Changes from 11 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
22f8848
Colors plugin
igorlukanin f4015db
Make linter happy
igorlukanin 7341686
Rewrite docs for Colors
igorlukanin 98b71cd
Rearrange colors
igorlukanin cc6e584
Update docs/general/colors.md
dangreen 1901efe
Update docs/general/colors.md
dangreen 55bfe6b
feat: choose colors by chart type
dangreen 83bcd03
fix: make plugin pure for tree-shaking
dangreen 29a89bc
feat: check all datasets and elements options before apply colors
dangreen ca612bb
test: disable colors plugin for tests
dangreen 06f4ca6
test: update test
LeeLenaleee 6bf7992
Fix: rgba
igorlukanin ede7584
Typos
igorlukanin 90406d7
Add color
igorlukanin 5f690e6
Move definition
igorlukanin 9566500
Remove plugin refs, add a link to awesome
igorlukanin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,55 +1,155 @@ | ||
| # Colors | ||
|
|
||
| When supplying colors to Chart options, you can use a number of formats. You can specify the color as a string in hexadecimal, RGB, or HSL notations. If a color is needed, but not specified, Chart.js will use the global default color. There are 3 color options, stored at `Chart.defaults`, to set: | ||
| Charts support three color options: | ||
| * for geometric elements, you can change *background* and *border* colors; | ||
| * for textual elements, you can change the *font* color. | ||
|
|
||
| | Name | Type | Default | Description | ||
| | ---- | ---- | ------- | ----------- | ||
| | `backgroundColor` | `Color` | `rgba(0, 0, 0, 0.1)` | Background color. | ||
| | `borderColor` | `Color` | `rgba(0, 0, 0, 0.1)` | Border color. | ||
| | `color` | `Color` | `#666` | Font color. | ||
| Also, you can change the whole [canvas background](.../configuration/canvas-background.html). | ||
|
|
||
| You can also pass a [CanvasGradient](https://developer.mozilla.org/en-US/docs/Web/API/CanvasGradient) object. You will need to create this before passing to the chart, but using it you can achieve some interesting effects. | ||
| ## Default colors | ||
|
|
||
| ## Patterns and Gradients | ||
| If a color is not specified, a global default color from `Chart.defaults` is used: | ||
|
|
||
| | Name | Type | Description | Default value | ||
| | ---- | ---- | ----------- | ------------- | ||
| | `backgroundColor` | [`Color`](../api/#color) | Background color | `rgba(0, 0, 0, 0.1)` | ||
| | `borderColor` | [`Color`](../api/#color) | Border color | `rgba(0, 0, 0, 0.1)` | ||
| | `color` | [`Color`](../api/#color) | Font color | `#666` | ||
|
|
||
| You can reset default colors by updating these properties of `Chart.defaults`: | ||
|
|
||
| ```javascript | ||
| Chart.defaults.backgroundColor = '#9BD0F5'; | ||
| Chart.defaults.borderColor = '#36A2EB'; | ||
| ``` | ||
|
|
||
| An alternative option is to pass a [CanvasPattern](https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern) or [CanvasGradient](https://developer.mozilla.org/en/docs/Web/API/CanvasGradient) object instead of a string colour. | ||
| ### Per-dataset color settings | ||
|
|
||
| For example, if you wanted to fill a dataset with a pattern from an image you could do the following. | ||
| If your chart has multiple datasets, using default colors would make individual datasets indistiguishable. In that case, you can set `backgroundColor` and `borderColor` for each dataset: | ||
|
|
||
| ```javascript | ||
| const data = { | ||
| labels: ['A', 'B', 'C'], | ||
| datasets: [ | ||
| { | ||
| label: 'Dataset 1', | ||
| data: [1, 2, 3], | ||
| borderColor: '#36A2EB', | ||
| backgroundColor: '#9BD0F5', | ||
| }, | ||
| { | ||
| label: 'Dataset 2', | ||
| data: [2, 3, 4], | ||
| borderColor: '#FF6384', | ||
| backgroundColor: '#FFB1C1', | ||
| } | ||
| ] | ||
| }; | ||
| ``` | ||
|
|
||
| However, setting colors for each dataset might require additional work that you'd rather not do. In that case, consider using the following plugins with pre-defined or generated palettes. | ||
|
|
||
| ### Default color series | ||
|
|
||
| If you don't have any preference for colors, you can use the built-in `Colors` plugin. It will cycle through a series of seven Chart.js brand colors: | ||
|
|
||
| <div style="max-width: 500px;"> | ||
|
|
||
|  | ||
|
|
||
| </div> | ||
|
|
||
| All you need is to import and register the plugin: | ||
|
|
||
| ```javascript | ||
| import { Colors } from 'chart.js'; | ||
|
|
||
| Chart.register(Colors); | ||
| ``` | ||
|
|
||
| :::tip Note | ||
|
|
||
| If you are using UMD version of Chart.js, this plugin will be enabled by default. You can disable it by setting option `enabled` to `false`: | ||
|
|
||
| ```js | ||
| const options = { | ||
| plugins: { | ||
| colors: { | ||
| enabled: false | ||
| } | ||
| } | ||
| }; | ||
| ``` | ||
|
|
||
| ::: | ||
|
|
||
| ### Advanced color series | ||
|
|
||
| If a limited-size series of colors is not enough, you can use [`chartjs-plugin-autocolors`](https://github.com/kurkle/chartjs-plugin-autocolors) that generates an unlimited number of distinct colors for every dataset or for every data point in every dataset: | ||
|
|
||
| <div style="max-width: 500px;"> | ||
|
|
||
|  | ||
|
|
||
| </div> | ||
|
|
||
| You can also use [`chartjs-plugin-colorschemes`](https://github.com/nagix/chartjs-plugin-colorschemes) that comes with dozens of [pre-defined color series](https://nagix.github.io/chartjs-plugin-colorschemes/colorchart.html) from well-known tools like Tableau and Microsoft Office: | ||
igorlukanin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| <div style="max-width: 500px;"> | ||
|
|
||
|  | ||
|
|
||
| </div> | ||
|
|
||
| ## Color formats | ||
|
|
||
| You can specify the color as a string in either of the following notations: | ||
|
|
||
| | Notation | Example | Example with transparency | ||
| | -------- | ------- | ------------------------- | ||
| | [Hexademical](https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color) | `#36A2EB` | `#36A2EB80` | ||
| | [RGB](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb) or [RGBA](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgba) | `rgb(54, 162, 235)` | `rgba(54, 162, 235, 0.5)` | ||
| | [HSL](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl) or [HSLA](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsla) | `hsl(204, 82%, 57%)` | `hsla(204, 82%, 57%, 0.5)` | ||
|
|
||
| Alternatively, you can pass a [CanvasPattern](https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern) or [CanvasGradient](https://developer.mozilla.org/en/docs/Web/API/CanvasGradient) object instead of a string color to achieve some interesting effects. | ||
|
|
||
| ## Patterns and Gradients | ||
|
|
||
| For example, you can fill a dataset with a pattern from an image. | ||
|
|
||
| ```javascript | ||
| const img = new Image(); | ||
| img.src = 'https://example.com/my_image.png'; | ||
| img.onload = function() { | ||
| const ctx = document.getElementById('canvas').getContext('2d'); | ||
| const fillPattern = ctx.createPattern(img, 'repeat'); | ||
|
|
||
| const chart = new Chart(ctx, { | ||
| data: { | ||
| labels: ['Item 1', 'Item 2', 'Item 3'], | ||
| datasets: [{ | ||
| data: [10, 20, 30], | ||
| backgroundColor: fillPattern | ||
| }] | ||
| } | ||
| }); | ||
| img.onload = () => { | ||
| const ctx = document.getElementById('canvas').getContext('2d'); | ||
| const fillPattern = ctx.createPattern(img, 'repeat'); | ||
|
|
||
| const chart = new Chart(ctx, { | ||
| data: { | ||
| labels: ['Item 1', 'Item 2', 'Item 3'], | ||
| datasets: [{ | ||
| data: [10, 20, 30], | ||
| backgroundColor: fillPattern | ||
| }] | ||
| } | ||
| }); | ||
| }; | ||
| ``` | ||
| Pattern fills can help viewers with vision deficiencies (e.g., color-blindness or partial sight) [more easily understand your data](http://betweentwobrackets.com/data-graphics-and-colour-vision/). | ||
|
|
||
| Using pattern fills for data graphics can help viewers with vision deficiencies (e.g. color-blindness or partial sight) to [more easily understand your data](http://betweentwobrackets.com/data-graphics-and-colour-vision/). | ||
|
|
||
| Using the [Patternomaly](https://github.com/ashiguruma/patternomaly) library you can generate patterns to fill datasets. | ||
| You can use the [Patternomaly](https://github.com/ashiguruma/patternomaly) library to generate patterns to fill datasets: | ||
|
|
||
| ```javascript | ||
| const chartData = { | ||
| datasets: [{ | ||
| data: [45, 25, 20, 10], | ||
| backgroundColor: [ | ||
| pattern.draw('square', '#ff6384'), | ||
| pattern.draw('circle', '#36a2eb'), | ||
| pattern.draw('diamond', '#cc65fe'), | ||
| pattern.draw('triangle', '#ffce56') | ||
| ] | ||
| }], | ||
| labels: ['Red', 'Blue', 'Purple', 'Yellow'] | ||
| datasets: [{ | ||
| data: [45, 25, 20, 10], | ||
| backgroundColor: [ | ||
| pattern.draw('square', '#ff6384'), | ||
| pattern.draw('circle', '#36a2eb'), | ||
| pattern.draw('diamond', '#cc65fe'), | ||
| pattern.draw('triangle', '#ffce56') | ||
| ] | ||
| }], | ||
| labels: ['Red', 'Blue', 'Purple', 'Yellow'] | ||
| }; | ||
| ``` | ||
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| import type {Chart, ChartDataset} from '../types'; | ||
|
|
||
| export interface ColorsPluginOptions { | ||
| enabled?: boolean; | ||
| } | ||
|
|
||
| type DatasetColorizer = (dataset: ChartDataset, i: number) => void; | ||
|
|
||
| interface ColorsDescriptor { | ||
| backgroundColor?: unknown; | ||
| borderColor?: unknown; | ||
| } | ||
|
|
||
| const BORDER_COLORS = [ | ||
igorlukanin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 'rgb(54, 162, 235)', // blue | ||
| 'rgb(255, 99, 132)', // red | ||
| 'rgb(255, 159, 64)', // orange | ||
| 'rgb(255, 205, 86)', // yellow | ||
| 'rgb(75, 192, 192)', // green | ||
| 'rgb(153, 102, 255)', // purple | ||
| 'rgb(201, 203, 207)' // grey | ||
| ]; | ||
|
|
||
| // Primary colors with 50% transparency | ||
| const BACKGROUND_COLORS = /* #__PURE__ */ BORDER_COLORS.map(_ => _.replace(')', ', 0.5)')); | ||
igorlukanin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| function getBorderColor(i: number) { | ||
| return BORDER_COLORS[i % BORDER_COLORS.length]; | ||
| } | ||
|
|
||
| function getBackgroundColor(i: number) { | ||
| return BACKGROUND_COLORS[i % BACKGROUND_COLORS.length]; | ||
| } | ||
|
|
||
| function createDefaultDatasetColorizer() { | ||
| return (dataset: ChartDataset, i: number) => { | ||
| dataset.borderColor = getBorderColor(i); | ||
| dataset.backgroundColor = getBackgroundColor(i); | ||
| }; | ||
| } | ||
|
|
||
| function createDoughnutDatasetColorizer() { | ||
| let i = 0; | ||
|
|
||
| return (dataset: ChartDataset) => { | ||
| dataset.backgroundColor = dataset.data.map(() => getBorderColor(i++)); | ||
| }; | ||
| } | ||
|
|
||
| function createPolarAreaDatasetColorizer() { | ||
| let i = 0; | ||
|
|
||
| return (dataset: ChartDataset) => { | ||
| dataset.backgroundColor = dataset.data.map(() => getBackgroundColor(i++)); | ||
| }; | ||
| } | ||
|
|
||
| function containsColorsDefinitions( | ||
| descriptors: ColorsDescriptor[] | Record<string, ColorsDescriptor> | ||
| ) { | ||
| let k: number | string; | ||
|
|
||
| for (k in descriptors) { | ||
| if (descriptors[k].borderColor || descriptors[k].backgroundColor) { | ||
| return true; | ||
| } | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| export default { | ||
| id: 'colors', | ||
|
|
||
| defaults: { | ||
| enabled: true, | ||
| }, | ||
|
|
||
| beforeLayout(chart: Chart, _args, options: ColorsPluginOptions) { | ||
| if (!options.enabled) { | ||
| return; | ||
| } | ||
|
|
||
| const { | ||
| type, | ||
| options: {elements}, | ||
| data: {datasets} | ||
| } = chart.config; | ||
| let colorizer: DatasetColorizer; | ||
igorlukanin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| if (containsColorsDefinitions(datasets) || elements && containsColorsDefinitions(elements)) { | ||
| return; | ||
| } | ||
|
|
||
| if (type === 'doughnut') { | ||
| colorizer = createDoughnutDatasetColorizer(); | ||
| } else if (type === 'polarArea') { | ||
| colorizer = createPolarAreaDatasetColorizer(); | ||
| } else { | ||
| colorizer = createDefaultDatasetColorizer(); | ||
| } | ||
|
|
||
| datasets.forEach(colorizer); | ||
| } | ||
| }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| module.exports = { | ||
| config: { | ||
| type: 'bar', | ||
| data: { | ||
| labels: [0, 1, 2, 3, 4, 5], | ||
| datasets: [ | ||
| { | ||
| data: [0, 5, 10, null, -10, -5], | ||
| }, | ||
| { | ||
| data: [10, 2, 3, null, 10, 5] | ||
| } | ||
| ] | ||
| }, | ||
| options: { | ||
| scales: { | ||
| x: { | ||
| ticks: { | ||
| display: false, | ||
| } | ||
| }, | ||
| y: { | ||
| ticks: { | ||
| display: false, | ||
| } | ||
| } | ||
| }, | ||
| plugins: { | ||
| legend: false, | ||
| colors: { | ||
| enabled: true | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }; |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| module.exports = { | ||
| config: { | ||
| type: 'bubble', | ||
| data: { | ||
| datasets: [{ | ||
| data: [{x: 12, y: 54, r: 22.4}] | ||
| }, { | ||
| data: [{x: 18, y: 38, r: 25}] | ||
| }] | ||
| }, | ||
| options: { | ||
| scales: { | ||
| x: { | ||
| ticks: { | ||
| display: false, | ||
| } | ||
| }, | ||
| y: { | ||
| ticks: { | ||
| display: false, | ||
| } | ||
| } | ||
| }, | ||
| plugins: { | ||
| legend: false, | ||
| colors: { | ||
| enabled: true | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }; |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| module.exports = { | ||
| config: { | ||
| type: 'doughnut', | ||
| data: { | ||
| datasets: [ | ||
| { | ||
| data: [0, 2, 4, null, 6, 8] | ||
| }, | ||
| { | ||
| data: [5, 1, 6, 2, null, 9] | ||
| } | ||
| ] | ||
| }, | ||
| options: { | ||
| plugins: { | ||
| legend: false, | ||
| colors: { | ||
| enabled: true | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }; |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.