├── .clean-publish ├── .commitlintrc.json ├── .czrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── .nano-staged.json ├── .npmrc ├── .nvmrc ├── .prettierrc ├── .simple-git-hooks.json ├── .size-limit.json ├── CHANGELOG.md ├── LICENSE ├── LICENSE.md ├── README.md ├── netlify.toml ├── package.json ├── pnpm-lock.yaml ├── rollup.config.js ├── sandboxes ├── bar │ ├── grouped │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js │ ├── horizontal │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js │ ├── stacked │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js │ └── vertical │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js ├── bubble │ └── default │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js ├── chart │ ├── canvas │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js │ ├── events │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js │ ├── multitype │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js │ └── ref │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js ├── doughnut │ └── default │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js ├── line │ ├── area │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js │ ├── default │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js │ └── multiaxis │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js ├── pie │ └── default │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js ├── polarArea │ └── default │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js ├── radar │ └── default │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js ├── scatter │ └── default │ │ ├── App.tsx │ │ ├── index.html │ │ ├── index.tsx │ │ ├── package.json │ │ └── vite.config.js └── tsconfig.json ├── src ├── chart.tsx ├── index.ts ├── typedCharts.tsx ├── types.ts └── utils.ts ├── stories ├── Bar.tsx ├── Bubble.tsx ├── Chart.data.ts ├── Chart.tsx ├── Doughnut.tsx ├── Line.tsx ├── Pie.tsx ├── PolarArea.tsx ├── Radar.tsx ├── Scatter.tsx └── data.ts ├── test ├── .eslintrc.json ├── chart.test-d.tsx ├── chart.test.tsx └── setup.js ├── tsconfig.json ├── vite.config.js └── website ├── .gitignore ├── CNAME ├── README.md ├── babel.config.js ├── docs ├── chartjs-v2.mdx ├── chartjs-v3.mdx ├── components │ ├── bar.mdx │ ├── bubble.mdx │ ├── chart.mdx │ ├── docs.js │ ├── doughnut.mdx │ ├── index.mdx │ ├── line.mdx │ ├── pie.mdx │ ├── polar-area.mdx │ ├── radar.mdx │ └── scatter.mdx ├── docs.js ├── examples │ ├── area-chart.mdx │ ├── bubble-chart.mdx │ ├── chart-events.mdx │ ├── chart-ref.mdx │ ├── docs.js │ ├── doughnut-chart.mdx │ ├── gradient-chart.mdx │ ├── grouped-bar-chart.mdx │ ├── horizontal-bar-chart.mdx │ ├── index.mdx │ ├── line-chart.mdx │ ├── multiaxis-line-chart.mdx │ ├── multitype-chart.mdx │ ├── pie-chart.mdx │ ├── polar-area-chart.mdx │ ├── radar-chart.mdx │ ├── scatter-chart.mdx │ ├── stacked-bar-chart.mdx │ └── vertical-bar-chart.mdx ├── faq │ ├── canvas-context.md │ ├── chartjs-instance.md │ ├── docs.js │ ├── esm-only.md │ ├── fill-property.md │ ├── index.mdx │ ├── maintain-aspect-ratio.md │ ├── registered-element.md │ ├── registered-scale.md │ ├── typescript.md │ └── why-two.md ├── index.mdx ├── migration-to-v4.md ├── migration-to-v5.md ├── working-with-datasets.md └── working-with-events.md ├── docusaurus.config.js ├── package.json ├── pnpm-lock.yaml ├── sidebars.js ├── src ├── components │ ├── ContextProvider.tsx │ └── PropsTable.tsx └── css │ └── custom.css ├── static ├── .nojekyll └── img │ ├── favicon.ico │ └── logo.svg └── tsconfig.json /.clean-publish: -------------------------------------------------------------------------------- 1 | { 2 | "withoutPublish": true, 3 | "tempDir": "package", 4 | "fields": ["tsd"], 5 | "files": ["website"] 6 | } 7 | -------------------------------------------------------------------------------- /.commitlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@commitlint/config-conventional"], 3 | "rules": { 4 | "body-max-line-length": [0] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.czrc: -------------------------------------------------------------------------------- 1 | { 2 | "path": "@commitlint/cz-commitlint" 3 | } 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | root = true 4 | 5 | [*] 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | indent_style = space 11 | indent_size = 2 12 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | .publish/* 2 | dist/* 3 | lib/* 4 | node_modules/* 5 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "plugins": ["@typescript-eslint"], 4 | "extends": [ 5 | "standard", 6 | "standard-react", 7 | "plugin:prettier/recommended", 8 | "plugin:@typescript-eslint/recommended" 9 | ], 10 | "env": { 11 | "browser": true 12 | }, 13 | "parserOptions": { 14 | "ecmaVersion": "latest", 15 | "ecmaFeatures": { 16 | "jsx": true 17 | } 18 | }, 19 | "settings": { 20 | "react": { 21 | "version": "detect" 22 | } 23 | }, 24 | "rules": { 25 | "curly": [2, "multi-line"], 26 | "quotes": [2, "single", "avoid-escape"], 27 | "react/display-name": 0, 28 | "react/jsx-boolean-value": 1, 29 | "jsx-quotes": [1, "prefer-single"], 30 | "react/jsx-no-undef": 1, 31 | "react/jsx-sort-props": 0, 32 | "react/jsx-uses-react": 1, 33 | "react/jsx-uses-vars": 1, 34 | "react/no-did-mount-set-state": 1, 35 | "react/no-did-update-set-state": 1, 36 | "react/no-unknown-property": 1, 37 | "react/prop-types": 0, 38 | "react/react-in-jsx-scope": 1, 39 | "react/self-closing-comp": 1, 40 | "semi": [2, "always"], 41 | "strict": 0, 42 | "no-use-before-define": 0, 43 | "@typescript-eslint/no-use-before-define": 2 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # builds 7 | package 8 | dist 9 | storybook-static 10 | 11 | # misc 12 | .DS_Store 13 | .env 14 | .env.* 15 | 16 | npm-debug.log* 17 | 18 | # testing 19 | coverage 20 | -------------------------------------------------------------------------------- /.nano-staged.json: -------------------------------------------------------------------------------- 1 | { 2 | "**/*.{js,ts,tsx}": ["prettier --write", "eslint"] 3 | } 4 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | strict-peer-dependencies=false 2 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | lts/* 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "jsxSingleQuote": true, 4 | "semi": true, 5 | "tabWidth": 2, 6 | "bracketSpacing": true, 7 | "arrowParens": "avoid", 8 | "trailingComma": "es5" 9 | } 10 | -------------------------------------------------------------------------------- /.simple-git-hooks.json: -------------------------------------------------------------------------------- 1 | { 2 | "commit-msg": "pnpm commitlint --edit \"$1\"", 3 | "pre-commit": "pnpm nano-staged", 4 | "pre-push": "pnpm test" 5 | } 6 | -------------------------------------------------------------------------------- /.size-limit.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "dist/index.js", 4 | "limit": "1.6 KB", 5 | "webpack": false, 6 | "running": false 7 | }, 8 | { 9 | "path": "dist/index.js", 10 | "limit": "800 B", 11 | "import": "{ Chart }" 12 | } 13 | ] 14 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ## [5.2.0](https://github.com/reactchartjs/react-chartjs-2/compare/v5.1.0...v5.2.0) (2023-01-09) 6 | 7 | 8 | ### Features 9 | 10 | * restore compatability with webpack 4 ([#1146](https://github.com/reactchartjs/react-chartjs-2/issues/1146)) ([082c26d](https://github.com/reactchartjs/react-chartjs-2/commit/082c26d559f210af7c55c31a826fe4821a429700)) 11 | 12 | ## [5.1.0](https://github.com/reactchartjs/react-chartjs-2/compare/v5.0.1...v5.1.0) (2022-12-19) 13 | 14 | 15 | ### Features 16 | 17 | * restore CommonJS bundle ([#1137](https://github.com/reactchartjs/react-chartjs-2/issues/1137)) ([7db2643](https://github.com/reactchartjs/react-chartjs-2/commit/7db264337200c999bc987e0e288df08ef7813ee3)) 18 | 19 | ### [5.0.1](https://github.com/reactchartjs/react-chartjs-2/compare/v5.0.0...v5.0.1) (2022-11-17) 20 | 21 | 22 | ### Bug Fixes 23 | 24 | * remove chart.js v3 from peer dependencies ([7ae5702](https://github.com/reactchartjs/react-chartjs-2/commit/7ae57023783f4c64210119f0447bd1c0e1ba92e9)) 25 | 26 | ## [5.0.0](https://github.com/reactchartjs/react-chartjs-2/compare/v4.3.1...v5.0.0) (2022-11-17) 27 | 28 | 29 | ### ⚠ BREAKING CHANGES 30 | 31 | * no commonjs support 32 | 33 | ### Features 34 | 35 | * chart.js v4 support ([#1109](https://github.com/reactchartjs/react-chartjs-2/issues/1109)) ([deb2110](https://github.com/reactchartjs/react-chartjs-2/commit/deb211084757225e3ddb2574b567e805ba7eeeb6)) 36 | * package type module ([#1108](https://github.com/reactchartjs/react-chartjs-2/issues/1108)) ([6eb8ce7](https://github.com/reactchartjs/react-chartjs-2/commit/6eb8ce7f23654e46d17aedc104375112b2f2a955)) 37 | 38 | 39 | ### Bug Fixes 40 | 41 | * **deps:** update dependency chart.js to v4 ([#1104](https://github.com/reactchartjs/react-chartjs-2/issues/1104)) ([6192408](https://github.com/reactchartjs/react-chartjs-2/commit/61924087de28a7ee0bba6f61c50a0bde362b662c)) 42 | * **deps:** update dependency react-scripts to v5.0.1 ([#1049](https://github.com/reactchartjs/react-chartjs-2/issues/1049)) ([38a9796](https://github.com/reactchartjs/react-chartjs-2/commit/38a9796f1cefa63390d4eaf3eec960c77fe78d34)) 43 | * **deps:** update react monorepo to v18 ([#1031](https://github.com/reactchartjs/react-chartjs-2/issues/1031)) ([ad73425](https://github.com/reactchartjs/react-chartjs-2/commit/ad734256e173353222995b4edfbf7a8ad0dc96f3)) 44 | * **deps:** update react monorepo to v18.2.0 ([#1082](https://github.com/reactchartjs/react-chartjs-2/issues/1082)) ([72e7352](https://github.com/reactchartjs/react-chartjs-2/commit/72e7352fcdff182465bfdcd6a7f6c4579d062d01)) 45 | * **site:** [#1076](https://github.com/reactchartjs/react-chartjs-2/issues/1076) expand the docusaurus container content to give the sandboxes more space ([#1077](https://github.com/reactchartjs/react-chartjs-2/issues/1077)) ([b512e8d](https://github.com/reactchartjs/react-chartjs-2/commit/b512e8dc130e28c1284be77d4ef6c3a788b9e262)) 46 | 47 | ### [4.3.1](https://github.com/reactchartjs/react-chartjs-2/compare/v4.3.0...v4.3.1) (2022-07-13) 48 | 49 | 50 | ### Bug Fixes 51 | 52 | * update options without resetting chart ([#1061](https://github.com/reactchartjs/react-chartjs-2/issues/1061)) ([fa0a4bb](https://github.com/reactchartjs/react-chartjs-2/commit/fa0a4bbdb3d85735db289494c4bdf1da083a51da)) 53 | 54 | ## [4.3.0](https://github.com/reactchartjs/react-chartjs-2/compare/v4.2.0...v4.3.0) (2022-07-12) 55 | 56 | 57 | ### Features 58 | 59 | * assure redraw occurs when type changes ([#1054](https://github.com/reactchartjs/react-chartjs-2/issues/1054)) ([#1055](https://github.com/reactchartjs/react-chartjs-2/issues/1055)) ([bf0538f](https://github.com/reactchartjs/react-chartjs-2/commit/bf0538fd953ee878659d0b5647676fbfda460c76)) 60 | 61 | ## [4.2.0](https://github.com/reactchartjs/react-chartjs-2/compare/v4.1.0...v4.2.0) (2022-06-07) 62 | 63 | 64 | ### Features 65 | 66 | * implement passing updateMode property to chart's update method ([#1043](https://github.com/reactchartjs/react-chartjs-2/issues/1043)) ([96d2714](https://github.com/reactchartjs/react-chartjs-2/commit/96d2714c3df88346152a1b66b8fe729d43151e40)) 67 | 68 | ## [4.1.0](https://github.com/reactchartjs/react-chartjs-2/compare/v4.0.1...v4.1.0) (2022-04-07) 69 | 70 | 71 | ### Features 72 | 73 | * react 18 support ([#1034](https://github.com/reactchartjs/react-chartjs-2/issues/1034)) ([058035a](https://github.com/reactchartjs/react-chartjs-2/commit/058035a3e2da17ad9ee0c9f50793da3aaefb3913)) 74 | 75 | ### [4.0.1](https://github.com/reactchartjs/react-chartjs-2/compare/v4.0.0...v4.0.1) (2022-01-19) 76 | 77 | 78 | ### Bug Fixes 79 | 80 | * compatability with react 16 typings ([#987](https://github.com/reactchartjs/react-chartjs-2/issues/987)) ([4a01054](https://github.com/reactchartjs/react-chartjs-2/commit/4a010540ac01b1e4b299705ddd93f412df4875d1)), closes [#870](https://github.com/reactchartjs/react-chartjs-2/issues/870) 81 | * **deps:** update dependency @svgr/webpack to v6 ([#999](https://github.com/reactchartjs/react-chartjs-2/issues/999)) ([7611ebd](https://github.com/reactchartjs/react-chartjs-2/commit/7611ebdbdbf4e91991b1a15d393fbadf2de01246)) 82 | * **deps:** update dependency react-scripts to v5 ([#1001](https://github.com/reactchartjs/react-chartjs-2/issues/1001)) ([3936227](https://github.com/reactchartjs/react-chartjs-2/commit/3936227b4e6865bbd20419af4a5b0b49561f608c)) 83 | * **deps:** update docusaurus monorepo to v2.0.0-beta.14 ([#994](https://github.com/reactchartjs/react-chartjs-2/issues/994)) ([2a24ee9](https://github.com/reactchartjs/react-chartjs-2/commit/2a24ee92203c703d16c3784eccb0011b5b870802)) 84 | 85 | ## [4.0.0](https://github.com/reactchartjs/react-chartjs-2/compare/v3.3.0...v4.0.0) (2021-11-22) 86 | 87 | 88 | ### ⚠ BREAKING CHANGES 89 | 90 | * getDatasetAtEvent, getElementAtEvent and getElementsAtEvent props are removed, 91 | utils with the same names can used instead 92 | * New target browsers: ie 11 dropped for regular bundle, modern bundle builds for 93 | browsers with es6 modules support. 94 | * Functional data prop is removed 95 | * Added support of tree-shaking of Chart.js. Now you should register Chart.js 96 | components by yourself. 97 | * default export is renamed to Chart 98 | * Chart.js re-exports are removed 99 | 100 | ### Features 101 | 102 | * datasetIdKey prop ([#848](https://github.com/reactchartjs/react-chartjs-2/issues/848)) ([f895766](https://github.com/reactchartjs/react-chartjs-2/commit/f895766f012c0d3781d75b5f83adc6dbc8de0b03)) 103 | 104 | 105 | * default export is renamed to Chart ([#836](https://github.com/reactchartjs/react-chartjs-2/issues/836)) ([131daa0](https://github.com/reactchartjs/react-chartjs-2/commit/131daa008d3a3c280ba9e751c67ca926708b60e4)) 106 | * functional data prop is removed ([#840](https://github.com/reactchartjs/react-chartjs-2/issues/840)) ([b64dfb0](https://github.com/reactchartjs/react-chartjs-2/commit/b64dfb0430bf5817a5f8b8708551934ad426921e)) 107 | * getDatasetAtEvent, getElementAtEvent and getElementsAtEvent props are removed ([#845](https://github.com/reactchartjs/react-chartjs-2/issues/845)) ([6a9b2a7](https://github.com/reactchartjs/react-chartjs-2/commit/6a9b2a7527d23e7409c9273ad32eb100122ffb51)) 108 | * new target browsers ([#841](https://github.com/reactchartjs/react-chartjs-2/issues/841)) ([b1e83db](https://github.com/reactchartjs/react-chartjs-2/commit/b1e83db599e7f9b832c2fe1942b5e5f296730dd9)) 109 | * removed chart.js re-exports ([#835](https://github.com/reactchartjs/react-chartjs-2/issues/835)) ([30d5c2d](https://github.com/reactchartjs/react-chartjs-2/commit/30d5c2d457eae0b1142ea4ffb6eff8f583b60817)) 110 | * tree-shaking ([#839](https://github.com/reactchartjs/react-chartjs-2/issues/839)) ([fcd2849](https://github.com/reactchartjs/react-chartjs-2/commit/fcd2849037bb01d2eeadbfbc90c90054eb620d4c)) 111 | 112 | ## [3.3.0](https://github.com/reactchartjs/react-chartjs-2/compare/v3.2.0...v3.3.0) (2021-10-26) 113 | 114 | 115 | ### Features 116 | 117 | * export chart props types ([#810](https://github.com/reactchartjs/react-chartjs-2/issues/810)) ([82ab334](https://github.com/reactchartjs/react-chartjs-2/commit/82ab334c62939fb4924ed6021502fccfea29a5a2)), closes [#720](https://github.com/reactchartjs/react-chartjs-2/issues/720) 118 | 119 | 120 | ### Bug Fixes 121 | 122 | * data updating fix ([#807](https://github.com/reactchartjs/react-chartjs-2/issues/807)) ([45a50cc](https://github.com/reactchartjs/react-chartjs-2/commit/45a50cc46196ce64088a463b6f3b384a6c98eb06)), closes [#806](https://github.com/reactchartjs/react-chartjs-2/issues/806) 123 | 124 | ## [3.2.0](https://github.com/reactchartjs/react-chartjs-2/compare/v3.1.1...v3.2.0) (2021-10-21) 125 | 126 | 127 | ### Features 128 | 129 | * remove lodash ([#784](https://github.com/reactchartjs/react-chartjs-2/issues/784)) ([5594170](https://github.com/reactchartjs/react-chartjs-2/commit/559417024ef2fb34005727ff16d8fae8615cb071)) 130 | 131 | 132 | ### Bug Fixes 133 | 134 | * improve and fix rerendering ([#790](https://github.com/reactchartjs/react-chartjs-2/issues/790)) ([330fb1c](https://github.com/reactchartjs/react-chartjs-2/commit/330fb1cf0913bdbacda5ef755fb58c79482e1ea2)) 135 | * multitype chart typings ([#792](https://github.com/reactchartjs/react-chartjs-2/issues/792)) ([2f19eb3](https://github.com/reactchartjs/react-chartjs-2/commit/2f19eb3eba9681f383ca23e7a3a1f1c581c89061)) 136 | 137 | ### [3.1.1](https://github.com/reactchartjs/react-chartjs-2/compare/v3.1.0...v3.1.1) (2021-10-19) 138 | 139 | 140 | ### Bug Fixes 141 | 142 | * components' props types ([#782](https://github.com/reactchartjs/react-chartjs-2/issues/782)) ([eba8a27](https://github.com/reactchartjs/react-chartjs-2/commit/eba8a2794bb802dacc395a450110af8765fea868)), closes [#734](https://github.com/reactchartjs/react-chartjs-2/issues/734) [#741](https://github.com/reactchartjs/react-chartjs-2/issues/741) 143 | 144 | ## [3.1.0](https://github.com/reactchartjs/react-chartjs-2/compare/v2.4.0...v3.1.0) (2021-10-17) 145 | 146 | 147 | ### Features 148 | 149 | * Reduced package size 150 | 151 | 152 | ### Bug Fixes 153 | 154 | * minor types fixes ([#759](https://github.com/reactchartjs/react-chartjs-2/issues/759)) ([fe6c00f](https://github.com/reactchartjs/react-chartjs-2/commit/fe6c00f05cdc3099a66a7ac0c05fb5e6f216209a)) 155 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2020 Jeremy Ayerst 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Jeremy Ayerst 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-chartjs-2 2 | 3 | Logo 4 | 5 | React components for Chart.js, the most popular charting library. 6 | 7 | Supports Chart.js v4 and v3. 8 | 9 | [![NPM version][npm]][npm-url] 10 | [![Downloads][downloads]][downloads-url] 11 | [![Build status][build]][build-url] 12 | [![Coverage status][coverage]][coverage-url] 13 | [![Bundle size][size]][size-url] 14 | 15 | [npm]: https://img.shields.io/npm/v/react-chartjs-2.svg 16 | [npm-url]: https://www.npmjs.com/package/react-chartjs-2 17 | 18 | [downloads]: https://img.shields.io/npm/dm/react-chartjs-2.svg 19 | [downloads-url]: https://www.npmjs.com/package/react-chartjs-2 20 | 21 | [build]: https://img.shields.io/github/actions/workflow/status/reactchartjs/react-chartjs-2/ci.yml?branch=master 22 | [build-url]: https://github.com/reactchartjs/react-chartjs-2/actions 23 | 24 | [coverage]: https://img.shields.io/codecov/c/github/reactchartjs/react-chartjs-2.svg 25 | [coverage-url]: https://app.codecov.io/gh/reactchartjs/react-chartjs-2 26 | 27 | [size]: https://img.shields.io/bundlephobia/minzip/react-chartjs-2 28 | [size-url]: https://bundlephobia.com/package/react-chartjs-2 29 | 30 |
31 | Quickstart 32 |   •   33 | Docs 34 |   •   35 | Slack 36 |   •   37 | Stack Overflow 38 |
39 |
40 | 41 | ## Quickstart 42 | 43 | Install this library with peer dependencies: 44 | 45 | ```bash 46 | pnpm add react-chartjs-2 chart.js 47 | # or 48 | yarn add react-chartjs-2 chart.js 49 | # or 50 | npm i react-chartjs-2 chart.js 51 | ``` 52 | 53 | We recommend using `chart.js@^4.0.0`. 54 | 55 | Then, import and use individual components: 56 | 57 | ```jsx 58 | import { Doughnut } from 'react-chartjs-2'; 59 | 60 | 61 | ``` 62 | 63 | Need an API to fetch data? Consider [Cube](https://cube.dev/?ref=eco-react-chartjs), an open-source API for data apps. 64 | 65 |
66 | 67 | [![supported by Cube](https://user-images.githubusercontent.com/986756/154330861-d79ab8ec-aacb-4af8-9e17-1b28f1eccb01.svg)](https://cube.dev/?ref=eco-react-chartjs) 68 | 69 | ## Docs 70 | 71 | - [Migration to v4](https://react-chartjs-2.js.org/docs/migration-to-v4) 72 | - [Working with datasets](https://react-chartjs-2.js.org/docs/working-with-datasets) 73 | - [Working with events](https://react-chartjs-2.js.org/docs/working-with-events) 74 | - [FAQ](https://react-chartjs-2.js.org/faq) 75 | - [Components](https://react-chartjs-2.js.org/components) 76 | - [Examples](https://react-chartjs-2.js.org/examples) 77 | 78 | ## License 79 | 80 | [MIT Licensed](LICENSE) 81 | Copyright (c) 2020 Jeremy Ayerst 82 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build.environment] 2 | NPM_FLAGS = "--version" # prevent Netlify npm install 3 | [build] 4 | publish = "website/build" 5 | command = "npx pnpm i --store=node_modules/.pnpm-store && cd website && npx pnpm i --store=node_modules/.pnpm-store && npx pnpm build" 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-chartjs-2", 3 | "type": "module", 4 | "version": "5.2.0", 5 | "description": "React components for Chart.js", 6 | "author": "Jeremy Ayerst", 7 | "homepage": "https://github.com/reactchartjs/react-chartjs-2", 8 | "license": "MIT", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/reactchartjs/react-chartjs-2.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/reactchartjs/react-chartjs-2/issues" 15 | }, 16 | "keywords": [ 17 | "chart", 18 | "chart-js", 19 | "chart.js", 20 | "react-chartjs-2", 21 | "react chart.js", 22 | "react-chart.js" 23 | ], 24 | "sideEffects": false, 25 | "types": "./dist/index.d.ts", 26 | "exports": "./src/index.ts", 27 | "publishConfig": { 28 | "main": "./dist/index.cjs", 29 | "module": "./dist/index.js", 30 | "exports": { 31 | "types": "./dist/index.d.ts", 32 | "import": "./dist/index.js", 33 | "require": "./dist/index.cjs" 34 | }, 35 | "directory": "package" 36 | }, 37 | "files": [ 38 | "dist" 39 | ], 40 | "scripts": { 41 | "prepublishOnly": "pnpm test && pnpm build && del ./package && clean-publish", 42 | "postpublish": "del ./package", 43 | "emitDeclarations": "tsc --emitDeclarationOnly", 44 | "build": "rollup -c && pnpm emitDeclarations", 45 | "start:storybook": "start-storybook -p 6006 --ci", 46 | "build:storybook": "del ./storybook-static; NODE_ENV=production build-storybook", 47 | "test:lint": "eslint \"src/**/*.{ts,tsx}\" \"stories/**/*.{ts,tsx}\" \"sandboxes/**/*.{ts,tsx}\" \"test/**/*.{ts,tsx}\"", 48 | "test:unit": "vitest run --coverage", 49 | "test:unit:watch": "vitest watch", 50 | "test:size": "size-limit", 51 | "test:typings": "tsd", 52 | "test": "pnpm test:lint && pnpm test:unit", 53 | "format": "prettier --write src", 54 | "commit": "cz", 55 | "bumpVersion": "standard-version", 56 | "createGithubRelease": "simple-github-release", 57 | "release": "pnpm bumpVersion && git push origin master --tags && pnpm createGithubRelease", 58 | "updateGitHooks": "simple-git-hooks" 59 | }, 60 | "peerDependencies": { 61 | "chart.js": "^4.1.1", 62 | "react": "^16.8.0 || ^17.0.0 || ^18.0.0" 63 | }, 64 | "devDependencies": { 65 | "@commitlint/cli": "^17.0.0", 66 | "@commitlint/config-conventional": "^17.0.0", 67 | "@commitlint/cz-commitlint": "^17.0.0", 68 | "@rollup/plugin-node-resolve": "^15.0.1", 69 | "@size-limit/preset-big-lib": "^8.0.0", 70 | "@storybook/addon-actions": "^6.3.12", 71 | "@storybook/addon-controls": "^6.3.12", 72 | "@storybook/addon-docs": "^6.3.12", 73 | "@storybook/addons": "^6.3.12", 74 | "@storybook/builder-vite": "^0.2.5", 75 | "@storybook/client-api": "^6.5.13", 76 | "@storybook/client-logger": "^6.5.13", 77 | "@storybook/react": "^6.3.12", 78 | "@swc/core": "^1.3.17", 79 | "@swc/helpers": "^0.4.0", 80 | "@testing-library/jest-dom": "^5.5.0", 81 | "@testing-library/react": "^13.0.0", 82 | "@types/faker": "^5.5.8", 83 | "@types/node": "^18.0.0", 84 | "@types/react": "^18.0.0", 85 | "@types/react-dom": "^18.0.0", 86 | "@types/testing-library__jest-dom": "^5.14.5", 87 | "@typescript-eslint/eslint-plugin": "^5.0.0", 88 | "@typescript-eslint/parser": "^5.0.0", 89 | "@vitejs/plugin-react": "^3.0.0", 90 | "@vitest/coverage-c8": "^0.27.0", 91 | "browserslist": "^4.17.3", 92 | "chart.js": "^4.1.1", 93 | "chartjs-adapter-date-fns": "^3.0.0", 94 | "chartjs-plugin-annotation": "^2.0.1", 95 | "chartjs-plugin-zoom": "^2.0.0", 96 | "clean-publish": "^4.0.0", 97 | "commitizen": "^4.2.4", 98 | "date-fns": "^2.25.0", 99 | "del-cli": "^5.0.0", 100 | "eslint": "^7.32.0", 101 | "eslint-config-prettier": "^8.3.0", 102 | "eslint-config-standard": "^16.0.3", 103 | "eslint-config-standard-react": "^12.0.0", 104 | "eslint-plugin-import": "^2.25.1", 105 | "eslint-plugin-node": "^11.0.0", 106 | "eslint-plugin-prettier": "^4.0.0", 107 | "eslint-plugin-promise": "^5.1.0", 108 | "eslint-plugin-react": "^7.17.0", 109 | "faker": "^5.5.3", 110 | "jsdom": "^21.0.0", 111 | "nano-staged": "^0.8.0", 112 | "prettier": "^2.0.4", 113 | "react": "^18.0.0", 114 | "react-dom": "^18.0.0", 115 | "react-test-renderer": "^18.0.0", 116 | "rollup": "^3.3.0", 117 | "rollup-plugin-swc3": "^0.8.0", 118 | "simple-git-hooks": "^2.6.1", 119 | "simple-github-release": "^1.0.0", 120 | "size-limit": "^8.0.0", 121 | "standard-version": "^9.3.1", 122 | "tsd": "^0.25.0", 123 | "typescript": "^4.9.4", 124 | "vite": "^4.0.0", 125 | "vitest": "^0.27.0", 126 | "vitest-canvas-mock": "^0.2.1" 127 | }, 128 | "tsd": { 129 | "directory": "./test", 130 | "compilerOptions": { 131 | "paths": { 132 | "react-chartjs-2": [ 133 | "./src" 134 | ] 135 | } 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import { swc } from 'rollup-plugin-swc3'; 2 | import { nodeResolve } from '@rollup/plugin-node-resolve'; 3 | import pkg from './package.json' assert { type: 'json' }; 4 | 5 | const extensions = ['.js', '.ts', '.tsx']; 6 | const external = _ => /node_modules/.test(_) && !/@swc\/helpers/.test(_); 7 | const plugins = targets => [ 8 | nodeResolve({ 9 | extensions, 10 | }), 11 | swc({ 12 | tsconfig: false, 13 | jsc: { 14 | parser: { 15 | syntax: 'typescript', 16 | tsx: true, 17 | }, 18 | transform: { 19 | react: { 20 | useBuiltins: true, 21 | }, 22 | }, 23 | externalHelpers: true, 24 | }, 25 | env: { 26 | targets, 27 | }, 28 | module: { 29 | type: 'es6', 30 | }, 31 | sourceMaps: true, 32 | }), 33 | ]; 34 | 35 | export default { 36 | input: pkg.exports, 37 | plugins: plugins('defaults and supports es6-module'), 38 | external, 39 | output: [ 40 | { 41 | file: pkg.publishConfig.exports.import, 42 | format: 'es', 43 | sourcemap: true, 44 | }, 45 | { 46 | file: pkg.publishConfig.exports.require, 47 | format: 'cjs', 48 | sourcemap: true, 49 | }, 50 | ], 51 | }; 52 | -------------------------------------------------------------------------------- /sandboxes/bar/grouped/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Chart as ChartJS, 4 | CategoryScale, 5 | LinearScale, 6 | BarElement, 7 | Title, 8 | Tooltip, 9 | Legend, 10 | } from 'chart.js'; 11 | import { Bar } from 'react-chartjs-2'; 12 | import faker from 'faker'; 13 | 14 | ChartJS.register( 15 | CategoryScale, 16 | LinearScale, 17 | BarElement, 18 | Title, 19 | Tooltip, 20 | Legend 21 | ); 22 | 23 | export const options = { 24 | plugins: { 25 | title: { 26 | display: true, 27 | text: 'Chart.js Bar Chart - Stacked', 28 | }, 29 | }, 30 | responsive: true, 31 | interaction: { 32 | mode: 'index' as const, 33 | intersect: false, 34 | }, 35 | scales: { 36 | x: { 37 | stacked: true, 38 | }, 39 | y: { 40 | stacked: true, 41 | }, 42 | }, 43 | }; 44 | 45 | const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; 46 | 47 | export const data = { 48 | labels, 49 | datasets: [ 50 | { 51 | label: 'Dataset 1', 52 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 53 | backgroundColor: 'rgb(255, 99, 132)', 54 | stack: 'Stack 0', 55 | }, 56 | { 57 | label: 'Dataset 2', 58 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 59 | backgroundColor: 'rgb(75, 192, 192)', 60 | stack: 'Stack 0', 61 | }, 62 | { 63 | label: 'Dataset 3', 64 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 65 | backgroundColor: 'rgb(53, 162, 235)', 66 | stack: 'Stack 1', 67 | }, 68 | ], 69 | }; 70 | 71 | export function App() { 72 | return ; 73 | } 74 | -------------------------------------------------------------------------------- /sandboxes/bar/grouped/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/bar/grouped/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/bar/grouped/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/bar/grouped/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/bar/horizontal/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Chart as ChartJS, 4 | CategoryScale, 5 | LinearScale, 6 | BarElement, 7 | Title, 8 | Tooltip, 9 | Legend, 10 | } from 'chart.js'; 11 | import { Bar } from 'react-chartjs-2'; 12 | import faker from 'faker'; 13 | 14 | ChartJS.register( 15 | CategoryScale, 16 | LinearScale, 17 | BarElement, 18 | Title, 19 | Tooltip, 20 | Legend 21 | ); 22 | 23 | export const options = { 24 | indexAxis: 'y' as const, 25 | elements: { 26 | bar: { 27 | borderWidth: 2, 28 | }, 29 | }, 30 | responsive: true, 31 | plugins: { 32 | legend: { 33 | position: 'right' as const, 34 | }, 35 | title: { 36 | display: true, 37 | text: 'Chart.js Horizontal Bar Chart', 38 | }, 39 | }, 40 | }; 41 | 42 | const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; 43 | 44 | export const data = { 45 | labels, 46 | datasets: [ 47 | { 48 | label: 'Dataset 1', 49 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 50 | borderColor: 'rgb(255, 99, 132)', 51 | backgroundColor: 'rgba(255, 99, 132, 0.5)', 52 | }, 53 | { 54 | label: 'Dataset 2', 55 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 56 | borderColor: 'rgb(53, 162, 235)', 57 | backgroundColor: 'rgba(53, 162, 235, 0.5)', 58 | }, 59 | ], 60 | }; 61 | 62 | export function App() { 63 | return ; 64 | } 65 | -------------------------------------------------------------------------------- /sandboxes/bar/horizontal/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/bar/horizontal/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/bar/horizontal/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/bar/horizontal/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/bar/stacked/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Chart as ChartJS, 4 | CategoryScale, 5 | LinearScale, 6 | BarElement, 7 | Title, 8 | Tooltip, 9 | Legend, 10 | } from 'chart.js'; 11 | import { Bar } from 'react-chartjs-2'; 12 | import faker from 'faker'; 13 | 14 | ChartJS.register( 15 | CategoryScale, 16 | LinearScale, 17 | BarElement, 18 | Title, 19 | Tooltip, 20 | Legend 21 | ); 22 | 23 | export const options = { 24 | plugins: { 25 | title: { 26 | display: true, 27 | text: 'Chart.js Bar Chart - Stacked', 28 | }, 29 | }, 30 | responsive: true, 31 | scales: { 32 | x: { 33 | stacked: true, 34 | }, 35 | y: { 36 | stacked: true, 37 | }, 38 | }, 39 | }; 40 | 41 | const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; 42 | 43 | export const data = { 44 | labels, 45 | datasets: [ 46 | { 47 | label: 'Dataset 1', 48 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 49 | backgroundColor: 'rgb(255, 99, 132)', 50 | }, 51 | { 52 | label: 'Dataset 2', 53 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 54 | backgroundColor: 'rgb(75, 192, 192)', 55 | }, 56 | { 57 | label: 'Dataset 3', 58 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 59 | backgroundColor: 'rgb(53, 162, 235)', 60 | }, 61 | ], 62 | }; 63 | 64 | export function App() { 65 | return ; 66 | } 67 | -------------------------------------------------------------------------------- /sandboxes/bar/stacked/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/bar/stacked/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/bar/stacked/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/bar/stacked/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/bar/vertical/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Chart as ChartJS, 4 | CategoryScale, 5 | LinearScale, 6 | BarElement, 7 | Title, 8 | Tooltip, 9 | Legend, 10 | } from 'chart.js'; 11 | import { Bar } from 'react-chartjs-2'; 12 | import faker from 'faker'; 13 | 14 | ChartJS.register( 15 | CategoryScale, 16 | LinearScale, 17 | BarElement, 18 | Title, 19 | Tooltip, 20 | Legend 21 | ); 22 | 23 | export const options = { 24 | responsive: true, 25 | plugins: { 26 | legend: { 27 | position: 'top' as const, 28 | }, 29 | title: { 30 | display: true, 31 | text: 'Chart.js Bar Chart', 32 | }, 33 | }, 34 | }; 35 | 36 | const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; 37 | 38 | export const data = { 39 | labels, 40 | datasets: [ 41 | { 42 | label: 'Dataset 1', 43 | data: labels.map(() => faker.datatype.number({ min: 0, max: 1000 })), 44 | backgroundColor: 'rgba(255, 99, 132, 0.5)', 45 | }, 46 | { 47 | label: 'Dataset 2', 48 | data: labels.map(() => faker.datatype.number({ min: 0, max: 1000 })), 49 | backgroundColor: 'rgba(53, 162, 235, 0.5)', 50 | }, 51 | ], 52 | }; 53 | 54 | export function App() { 55 | return ; 56 | } 57 | -------------------------------------------------------------------------------- /sandboxes/bar/vertical/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/bar/vertical/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/bar/vertical/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/bar/vertical/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/bubble/default/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Chart as ChartJS, 4 | LinearScale, 5 | PointElement, 6 | Tooltip, 7 | Legend, 8 | } from 'chart.js'; 9 | import { Bubble } from 'react-chartjs-2'; 10 | import faker from 'faker'; 11 | 12 | ChartJS.register(LinearScale, PointElement, Tooltip, Legend); 13 | 14 | export const options = { 15 | scales: { 16 | y: { 17 | beginAtZero: true, 18 | }, 19 | }, 20 | }; 21 | 22 | export const data = { 23 | datasets: [ 24 | { 25 | label: 'Red dataset', 26 | data: Array.from({ length: 50 }, () => ({ 27 | x: faker.datatype.number({ min: -100, max: 100 }), 28 | y: faker.datatype.number({ min: -100, max: 100 }), 29 | r: faker.datatype.number({ min: 5, max: 20 }), 30 | })), 31 | backgroundColor: 'rgba(255, 99, 132, 0.5)', 32 | }, 33 | { 34 | label: 'Blue dataset', 35 | data: Array.from({ length: 50 }, () => ({ 36 | x: faker.datatype.number({ min: -100, max: 100 }), 37 | y: faker.datatype.number({ min: -100, max: 100 }), 38 | r: faker.datatype.number({ min: 5, max: 20 }), 39 | })), 40 | backgroundColor: 'rgba(53, 162, 235, 0.5)', 41 | }, 42 | ], 43 | }; 44 | 45 | export function App() { 46 | return ; 47 | } 48 | -------------------------------------------------------------------------------- /sandboxes/bubble/default/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/bubble/default/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/bubble/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/bubble/default/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/chart/canvas/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef, useEffect, useState } from 'react'; 2 | import type { ChartData, ChartArea } from 'chart.js'; 3 | import { 4 | Chart as ChartJS, 5 | CategoryScale, 6 | LinearScale, 7 | PointElement, 8 | LineElement, 9 | Tooltip, 10 | Legend, 11 | } from 'chart.js'; 12 | import { Chart } from 'react-chartjs-2'; 13 | import faker from 'faker'; 14 | 15 | ChartJS.register( 16 | CategoryScale, 17 | LinearScale, 18 | PointElement, 19 | LineElement, 20 | Tooltip, 21 | Legend 22 | ); 23 | 24 | const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; 25 | const colors = [ 26 | 'red', 27 | 'orange', 28 | 'yellow', 29 | 'lime', 30 | 'green', 31 | 'teal', 32 | 'blue', 33 | 'purple', 34 | ]; 35 | 36 | export const data = { 37 | labels, 38 | datasets: [ 39 | { 40 | label: 'Dataset 1', 41 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 42 | }, 43 | { 44 | label: 'Dataset 2', 45 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 46 | }, 47 | ], 48 | }; 49 | 50 | function createGradient(ctx: CanvasRenderingContext2D, area: ChartArea) { 51 | const colorStart = faker.random.arrayElement(colors); 52 | const colorMid = faker.random.arrayElement( 53 | colors.filter(color => color !== colorStart) 54 | ); 55 | const colorEnd = faker.random.arrayElement( 56 | colors.filter(color => color !== colorStart && color !== colorMid) 57 | ); 58 | 59 | const gradient = ctx.createLinearGradient(0, area.bottom, 0, area.top); 60 | 61 | gradient.addColorStop(0, colorStart); 62 | gradient.addColorStop(0.5, colorMid); 63 | gradient.addColorStop(1, colorEnd); 64 | 65 | return gradient; 66 | } 67 | 68 | export function App() { 69 | const chartRef = useRef(null); 70 | const [chartData, setChartData] = useState>({ 71 | datasets: [], 72 | }); 73 | 74 | useEffect(() => { 75 | const chart = chartRef.current; 76 | 77 | if (!chart) { 78 | return; 79 | } 80 | 81 | const chartData = { 82 | ...data, 83 | datasets: data.datasets.map(dataset => ({ 84 | ...dataset, 85 | borderColor: createGradient(chart.ctx, chart.chartArea), 86 | })), 87 | }; 88 | 89 | setChartData(chartData); 90 | }, []); 91 | 92 | return ; 93 | } 94 | -------------------------------------------------------------------------------- /sandboxes/chart/canvas/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/chart/canvas/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/chart/canvas/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/chart/canvas/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/chart/events/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { MouseEvent, useRef } from 'react'; 2 | import type { InteractionItem } from 'chart.js'; 3 | import { 4 | Chart as ChartJS, 5 | LinearScale, 6 | CategoryScale, 7 | BarElement, 8 | PointElement, 9 | LineElement, 10 | Legend, 11 | Tooltip, 12 | } from 'chart.js'; 13 | import { 14 | Chart, 15 | getDatasetAtEvent, 16 | getElementAtEvent, 17 | getElementsAtEvent, 18 | } from 'react-chartjs-2'; 19 | import faker from 'faker'; 20 | 21 | ChartJS.register( 22 | LinearScale, 23 | CategoryScale, 24 | BarElement, 25 | PointElement, 26 | LineElement, 27 | Legend, 28 | Tooltip 29 | ); 30 | 31 | export const options = { 32 | scales: { 33 | y: { 34 | beginAtZero: true, 35 | }, 36 | }, 37 | }; 38 | 39 | const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; 40 | 41 | export const data = { 42 | labels, 43 | datasets: [ 44 | { 45 | type: 'line' as const, 46 | label: 'Dataset 1', 47 | borderColor: 'rgb(255, 99, 132)', 48 | borderWidth: 2, 49 | fill: false, 50 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 51 | }, 52 | { 53 | type: 'bar' as const, 54 | label: 'Dataset 2', 55 | backgroundColor: 'rgb(75, 192, 192)', 56 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 57 | borderColor: 'white', 58 | borderWidth: 2, 59 | }, 60 | { 61 | type: 'bar' as const, 62 | label: 'Dataset 3', 63 | backgroundColor: 'rgb(53, 162, 235)', 64 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 65 | }, 66 | ], 67 | }; 68 | 69 | export function App() { 70 | const printDatasetAtEvent = (dataset: InteractionItem[]) => { 71 | if (!dataset.length) return; 72 | 73 | const datasetIndex = dataset[0].datasetIndex; 74 | 75 | console.log(data.datasets[datasetIndex].label); 76 | }; 77 | 78 | const printElementAtEvent = (element: InteractionItem[]) => { 79 | if (!element.length) return; 80 | 81 | const { datasetIndex, index } = element[0]; 82 | 83 | console.log(data.labels[index], data.datasets[datasetIndex].data[index]); 84 | }; 85 | 86 | const printElementsAtEvent = (elements: InteractionItem[]) => { 87 | if (!elements.length) return; 88 | 89 | console.log(elements.length); 90 | }; 91 | 92 | const chartRef = useRef(null); 93 | 94 | const onClick = (event: MouseEvent) => { 95 | const { current: chart } = chartRef; 96 | 97 | if (!chart) { 98 | return; 99 | } 100 | 101 | printDatasetAtEvent(getDatasetAtEvent(chart, event)); 102 | printElementAtEvent(getElementAtEvent(chart, event)); 103 | printElementsAtEvent(getElementsAtEvent(chart, event)); 104 | }; 105 | 106 | return ( 107 | 114 | ); 115 | } 116 | -------------------------------------------------------------------------------- /sandboxes/chart/events/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/chart/events/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/chart/events/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/chart/events/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/chart/multitype/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Chart as ChartJS, 4 | LinearScale, 5 | CategoryScale, 6 | BarElement, 7 | PointElement, 8 | LineElement, 9 | Legend, 10 | Tooltip, 11 | LineController, 12 | BarController, 13 | } from 'chart.js'; 14 | import { Chart } from 'react-chartjs-2'; 15 | import faker from 'faker'; 16 | 17 | ChartJS.register( 18 | LinearScale, 19 | CategoryScale, 20 | BarElement, 21 | PointElement, 22 | LineElement, 23 | Legend, 24 | Tooltip, 25 | LineController, 26 | BarController 27 | ); 28 | 29 | const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; 30 | 31 | export const data = { 32 | labels, 33 | datasets: [ 34 | { 35 | type: 'line' as const, 36 | label: 'Dataset 1', 37 | borderColor: 'rgb(255, 99, 132)', 38 | borderWidth: 2, 39 | fill: false, 40 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 41 | }, 42 | { 43 | type: 'bar' as const, 44 | label: 'Dataset 2', 45 | backgroundColor: 'rgb(75, 192, 192)', 46 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 47 | borderColor: 'white', 48 | borderWidth: 2, 49 | }, 50 | { 51 | type: 'bar' as const, 52 | label: 'Dataset 3', 53 | backgroundColor: 'rgb(53, 162, 235)', 54 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 55 | }, 56 | ], 57 | }; 58 | 59 | export function App() { 60 | return ; 61 | } 62 | -------------------------------------------------------------------------------- /sandboxes/chart/multitype/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/chart/multitype/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/chart/multitype/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/chart/multitype/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/chart/ref/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef, useEffect } from 'react'; 2 | import { 3 | Chart as ChartJS, 4 | LinearScale, 5 | CategoryScale, 6 | BarElement, 7 | PointElement, 8 | LineElement, 9 | Legend, 10 | Tooltip, 11 | } from 'chart.js'; 12 | import { Chart } from 'react-chartjs-2'; 13 | import faker from 'faker'; 14 | 15 | ChartJS.register( 16 | LinearScale, 17 | CategoryScale, 18 | BarElement, 19 | PointElement, 20 | LineElement, 21 | Legend, 22 | Tooltip 23 | ); 24 | 25 | const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; 26 | 27 | export const data = { 28 | labels, 29 | datasets: [ 30 | { 31 | type: 'line' as const, 32 | label: 'Dataset 1', 33 | borderColor: 'rgb(255, 99, 132)', 34 | borderWidth: 2, 35 | fill: false, 36 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 37 | }, 38 | { 39 | type: 'bar' as const, 40 | label: 'Dataset 2', 41 | backgroundColor: 'rgb(75, 192, 192)', 42 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 43 | borderColor: 'white', 44 | borderWidth: 2, 45 | }, 46 | { 47 | type: 'bar' as const, 48 | label: 'Dataset 3', 49 | backgroundColor: 'rgb(53, 162, 235)', 50 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 51 | }, 52 | ], 53 | }; 54 | 55 | function triggerTooltip(chart: ChartJS | null) { 56 | const tooltip = chart?.tooltip; 57 | 58 | if (!tooltip) { 59 | return; 60 | } 61 | 62 | if (tooltip.getActiveElements().length > 0) { 63 | tooltip.setActiveElements([], { x: 0, y: 0 }); 64 | } else { 65 | const { chartArea } = chart; 66 | 67 | tooltip.setActiveElements( 68 | [ 69 | { 70 | datasetIndex: 0, 71 | index: 2, 72 | }, 73 | { 74 | datasetIndex: 1, 75 | index: 2, 76 | }, 77 | ], 78 | { 79 | x: (chartArea.left + chartArea.right) / 2, 80 | y: (chartArea.top + chartArea.bottom) / 2, 81 | } 82 | ); 83 | } 84 | 85 | chart.update(); 86 | } 87 | 88 | export function App() { 89 | const chartRef = useRef(null); 90 | 91 | useEffect(() => { 92 | const chart = chartRef.current; 93 | 94 | triggerTooltip(chart); 95 | }, []); 96 | 97 | return ; 98 | } 99 | -------------------------------------------------------------------------------- /sandboxes/chart/ref/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/chart/ref/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/chart/ref/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/chart/ref/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/doughnut/default/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js'; 3 | import { Doughnut } from 'react-chartjs-2'; 4 | 5 | ChartJS.register(ArcElement, Tooltip, Legend); 6 | 7 | export const data = { 8 | labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], 9 | datasets: [ 10 | { 11 | label: '# of Votes', 12 | data: [12, 19, 3, 5, 2, 3], 13 | backgroundColor: [ 14 | 'rgba(255, 99, 132, 0.2)', 15 | 'rgba(54, 162, 235, 0.2)', 16 | 'rgba(255, 206, 86, 0.2)', 17 | 'rgba(75, 192, 192, 0.2)', 18 | 'rgba(153, 102, 255, 0.2)', 19 | 'rgba(255, 159, 64, 0.2)', 20 | ], 21 | borderColor: [ 22 | 'rgba(255, 99, 132, 1)', 23 | 'rgba(54, 162, 235, 1)', 24 | 'rgba(255, 206, 86, 1)', 25 | 'rgba(75, 192, 192, 1)', 26 | 'rgba(153, 102, 255, 1)', 27 | 'rgba(255, 159, 64, 1)', 28 | ], 29 | borderWidth: 1, 30 | }, 31 | ], 32 | }; 33 | 34 | export function App() { 35 | return ; 36 | } 37 | -------------------------------------------------------------------------------- /sandboxes/doughnut/default/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/doughnut/default/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/doughnut/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/doughnut/default/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/line/area/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Chart as ChartJS, 4 | CategoryScale, 5 | LinearScale, 6 | PointElement, 7 | LineElement, 8 | Title, 9 | Tooltip, 10 | Filler, 11 | Legend, 12 | } from 'chart.js'; 13 | import { Line } from 'react-chartjs-2'; 14 | import faker from 'faker'; 15 | 16 | ChartJS.register( 17 | CategoryScale, 18 | LinearScale, 19 | PointElement, 20 | LineElement, 21 | Title, 22 | Tooltip, 23 | Filler, 24 | Legend 25 | ); 26 | 27 | export const options = { 28 | responsive: true, 29 | plugins: { 30 | legend: { 31 | position: 'top' as const, 32 | }, 33 | title: { 34 | display: true, 35 | text: 'Chart.js Line Chart', 36 | }, 37 | }, 38 | }; 39 | 40 | const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; 41 | 42 | export const data = { 43 | labels, 44 | datasets: [ 45 | { 46 | fill: true, 47 | label: 'Dataset 2', 48 | data: labels.map(() => faker.datatype.number({ min: 0, max: 1000 })), 49 | borderColor: 'rgb(53, 162, 235)', 50 | backgroundColor: 'rgba(53, 162, 235, 0.5)', 51 | }, 52 | ], 53 | }; 54 | 55 | export function App() { 56 | return ; 57 | } 58 | -------------------------------------------------------------------------------- /sandboxes/line/area/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/line/area/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/line/area/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/line/area/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/line/default/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Chart as ChartJS, 4 | CategoryScale, 5 | LinearScale, 6 | PointElement, 7 | LineElement, 8 | Title, 9 | Tooltip, 10 | Legend, 11 | } from 'chart.js'; 12 | import { Line } from 'react-chartjs-2'; 13 | import faker from 'faker'; 14 | 15 | ChartJS.register( 16 | CategoryScale, 17 | LinearScale, 18 | PointElement, 19 | LineElement, 20 | Title, 21 | Tooltip, 22 | Legend 23 | ); 24 | 25 | export const options = { 26 | responsive: true, 27 | plugins: { 28 | legend: { 29 | position: 'top' as const, 30 | }, 31 | title: { 32 | display: true, 33 | text: 'Chart.js Line Chart', 34 | }, 35 | }, 36 | }; 37 | 38 | const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; 39 | 40 | export const data = { 41 | labels, 42 | datasets: [ 43 | { 44 | label: 'Dataset 1', 45 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 46 | borderColor: 'rgb(255, 99, 132)', 47 | backgroundColor: 'rgba(255, 99, 132, 0.5)', 48 | }, 49 | { 50 | label: 'Dataset 2', 51 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 52 | borderColor: 'rgb(53, 162, 235)', 53 | backgroundColor: 'rgba(53, 162, 235, 0.5)', 54 | }, 55 | ], 56 | }; 57 | 58 | export function App() { 59 | return ; 60 | } 61 | -------------------------------------------------------------------------------- /sandboxes/line/default/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/line/default/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/line/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/line/default/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/line/multiaxis/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Chart as ChartJS, 4 | CategoryScale, 5 | LinearScale, 6 | PointElement, 7 | LineElement, 8 | Title, 9 | Tooltip, 10 | Legend, 11 | } from 'chart.js'; 12 | import { Line } from 'react-chartjs-2'; 13 | import faker from 'faker'; 14 | 15 | ChartJS.register( 16 | CategoryScale, 17 | LinearScale, 18 | PointElement, 19 | LineElement, 20 | Title, 21 | Tooltip, 22 | Legend 23 | ); 24 | 25 | export const options = { 26 | responsive: true, 27 | interaction: { 28 | mode: 'index' as const, 29 | intersect: false, 30 | }, 31 | stacked: false, 32 | plugins: { 33 | title: { 34 | display: true, 35 | text: 'Chart.js Line Chart - Multi Axis', 36 | }, 37 | }, 38 | scales: { 39 | y: { 40 | type: 'linear' as const, 41 | display: true, 42 | position: 'left' as const, 43 | }, 44 | y1: { 45 | type: 'linear' as const, 46 | display: true, 47 | position: 'right' as const, 48 | grid: { 49 | drawOnChartArea: false, 50 | }, 51 | }, 52 | }, 53 | }; 54 | 55 | const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; 56 | 57 | export const data = { 58 | labels, 59 | datasets: [ 60 | { 61 | label: 'Dataset 1', 62 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 63 | borderColor: 'rgb(255, 99, 132)', 64 | backgroundColor: 'rgba(255, 99, 132, 0.5)', 65 | yAxisID: 'y', 66 | }, 67 | { 68 | label: 'Dataset 2', 69 | data: labels.map(() => faker.datatype.number({ min: -1000, max: 1000 })), 70 | borderColor: 'rgb(53, 162, 235)', 71 | backgroundColor: 'rgba(53, 162, 235, 0.5)', 72 | yAxisID: 'y1', 73 | }, 74 | ], 75 | }; 76 | 77 | export function App() { 78 | return ; 79 | } 80 | -------------------------------------------------------------------------------- /sandboxes/line/multiaxis/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/line/multiaxis/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/line/multiaxis/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/line/multiaxis/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/pie/default/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js'; 3 | import { Pie } from 'react-chartjs-2'; 4 | 5 | ChartJS.register(ArcElement, Tooltip, Legend); 6 | 7 | export const data = { 8 | labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], 9 | datasets: [ 10 | { 11 | label: '# of Votes', 12 | data: [12, 19, 3, 5, 2, 3], 13 | backgroundColor: [ 14 | 'rgba(255, 99, 132, 0.2)', 15 | 'rgba(54, 162, 235, 0.2)', 16 | 'rgba(255, 206, 86, 0.2)', 17 | 'rgba(75, 192, 192, 0.2)', 18 | 'rgba(153, 102, 255, 0.2)', 19 | 'rgba(255, 159, 64, 0.2)', 20 | ], 21 | borderColor: [ 22 | 'rgba(255, 99, 132, 1)', 23 | 'rgba(54, 162, 235, 1)', 24 | 'rgba(255, 206, 86, 1)', 25 | 'rgba(75, 192, 192, 1)', 26 | 'rgba(153, 102, 255, 1)', 27 | 'rgba(255, 159, 64, 1)', 28 | ], 29 | borderWidth: 1, 30 | }, 31 | ], 32 | }; 33 | 34 | export function App() { 35 | return ; 36 | } 37 | -------------------------------------------------------------------------------- /sandboxes/pie/default/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/pie/default/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/pie/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/pie/default/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/polarArea/default/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Chart as ChartJS, 4 | RadialLinearScale, 5 | ArcElement, 6 | Tooltip, 7 | Legend, 8 | } from 'chart.js'; 9 | import { PolarArea } from 'react-chartjs-2'; 10 | 11 | ChartJS.register(RadialLinearScale, ArcElement, Tooltip, Legend); 12 | 13 | export const data = { 14 | labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], 15 | datasets: [ 16 | { 17 | label: '# of Votes', 18 | data: [12, 19, 3, 5, 2, 3], 19 | backgroundColor: [ 20 | 'rgba(255, 99, 132, 0.5)', 21 | 'rgba(54, 162, 235, 0.5)', 22 | 'rgba(255, 206, 86, 0.5)', 23 | 'rgba(75, 192, 192, 0.5)', 24 | 'rgba(153, 102, 255, 0.5)', 25 | 'rgba(255, 159, 64, 0.5)', 26 | ], 27 | borderWidth: 1, 28 | }, 29 | ], 30 | }; 31 | 32 | export function App() { 33 | return ; 34 | } 35 | -------------------------------------------------------------------------------- /sandboxes/polarArea/default/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/polarArea/default/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/polarArea/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/polarArea/default/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/radar/default/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Chart as ChartJS, 4 | RadialLinearScale, 5 | PointElement, 6 | LineElement, 7 | Filler, 8 | Tooltip, 9 | Legend, 10 | } from 'chart.js'; 11 | import { Radar } from 'react-chartjs-2'; 12 | 13 | ChartJS.register( 14 | RadialLinearScale, 15 | PointElement, 16 | LineElement, 17 | Filler, 18 | Tooltip, 19 | Legend 20 | ); 21 | 22 | export const data = { 23 | labels: ['Thing 1', 'Thing 2', 'Thing 3', 'Thing 4', 'Thing 5', 'Thing 6'], 24 | datasets: [ 25 | { 26 | label: '# of Votes', 27 | data: [2, 9, 3, 5, 2, 3], 28 | backgroundColor: 'rgba(255, 99, 132, 0.2)', 29 | borderColor: 'rgba(255, 99, 132, 1)', 30 | borderWidth: 1, 31 | }, 32 | ], 33 | }; 34 | 35 | export function App() { 36 | return ; 37 | } 38 | -------------------------------------------------------------------------------- /sandboxes/radar/default/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/radar/default/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/radar/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/radar/default/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/scatter/default/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Chart as ChartJS, 4 | LinearScale, 5 | PointElement, 6 | LineElement, 7 | Tooltip, 8 | Legend, 9 | } from 'chart.js'; 10 | import { Scatter } from 'react-chartjs-2'; 11 | import faker from 'faker'; 12 | 13 | ChartJS.register(LinearScale, PointElement, LineElement, Tooltip, Legend); 14 | 15 | export const options = { 16 | scales: { 17 | y: { 18 | beginAtZero: true, 19 | }, 20 | }, 21 | }; 22 | 23 | export const data = { 24 | datasets: [ 25 | { 26 | label: 'A dataset', 27 | data: Array.from({ length: 100 }, () => ({ 28 | x: faker.datatype.number({ min: -100, max: 100 }), 29 | y: faker.datatype.number({ min: -100, max: 100 }), 30 | })), 31 | backgroundColor: 'rgba(255, 99, 132, 1)', 32 | }, 33 | ], 34 | }; 35 | 36 | export function App() { 37 | return ; 38 | } 39 | -------------------------------------------------------------------------------- /sandboxes/scatter/default/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /sandboxes/scatter/default/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { App } from './App.js'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | createRoot(rootElement!).render(); 8 | -------------------------------------------------------------------------------- /sandboxes/scatter/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "start": "vite" 5 | }, 6 | "dependencies": { 7 | "chart.js": "^4.0.0", 8 | "faker": "5.5.3", 9 | "react": "18.2.0", 10 | "react-chartjs-2": "^5.0.0", 11 | "react-dom": "18.2.0" 12 | }, 13 | "devDependencies": { 14 | "@types/faker": "5.5.9", 15 | "@types/react": "18.0.26", 16 | "@types/react-dom": "18.0.10", 17 | "@vitejs/plugin-react": "^3.0.0", 18 | "typescript": "4.9.4", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sandboxes/scatter/default/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | }); 7 | -------------------------------------------------------------------------------- /sandboxes/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "react-chartjs-2": ["../src"] 7 | } 8 | }, 9 | "include": ["."] 10 | } 11 | -------------------------------------------------------------------------------- /src/chart.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useRef, forwardRef } from 'react'; 2 | import { Chart as ChartJS } from 'chart.js'; 3 | import type { ChartType, DefaultDataPoint } from 'chart.js'; 4 | 5 | import type { ForwardedRef, ChartProps, BaseChartComponent } from './types.js'; 6 | import { 7 | reforwardRef, 8 | cloneData, 9 | setOptions, 10 | setLabels, 11 | setDatasets, 12 | } from './utils.js'; 13 | 14 | function ChartComponent< 15 | TType extends ChartType = ChartType, 16 | TData = DefaultDataPoint, 17 | TLabel = unknown 18 | >( 19 | props: ChartProps, 20 | ref: ForwardedRef> 21 | ) { 22 | const { 23 | height = 150, 24 | width = 300, 25 | redraw = false, 26 | datasetIdKey, 27 | type, 28 | data, 29 | options, 30 | plugins = [], 31 | fallbackContent, 32 | updateMode, 33 | ...canvasProps 34 | } = props as ChartProps; 35 | const canvasRef = useRef(null); 36 | const chartRef = useRef(); 37 | 38 | const renderChart = () => { 39 | if (!canvasRef.current) return; 40 | 41 | chartRef.current = new ChartJS(canvasRef.current, { 42 | type, 43 | data: cloneData(data, datasetIdKey), 44 | options: options && { ...options }, 45 | plugins, 46 | }); 47 | 48 | reforwardRef(ref, chartRef.current); 49 | }; 50 | 51 | const destroyChart = () => { 52 | reforwardRef(ref, null); 53 | 54 | if (chartRef.current) { 55 | chartRef.current.destroy(); 56 | chartRef.current = null; 57 | } 58 | }; 59 | 60 | useEffect(() => { 61 | if (!redraw && chartRef.current && options) { 62 | setOptions(chartRef.current, options); 63 | } 64 | }, [redraw, options]); 65 | 66 | useEffect(() => { 67 | if (!redraw && chartRef.current) { 68 | setLabels(chartRef.current.config.data, data.labels); 69 | } 70 | }, [redraw, data.labels]); 71 | 72 | useEffect(() => { 73 | if (!redraw && chartRef.current && data.datasets) { 74 | setDatasets(chartRef.current.config.data, data.datasets, datasetIdKey); 75 | } 76 | }, [redraw, data.datasets]); 77 | 78 | useEffect(() => { 79 | if (!chartRef.current) return; 80 | 81 | if (redraw) { 82 | destroyChart(); 83 | setTimeout(renderChart); 84 | } else { 85 | chartRef.current.update(updateMode); 86 | } 87 | }, [redraw, options, data.labels, data.datasets, updateMode]); 88 | 89 | useEffect(() => { 90 | if (!chartRef.current) return; 91 | 92 | destroyChart(); 93 | setTimeout(renderChart); 94 | }, [type]); 95 | 96 | useEffect(() => { 97 | renderChart(); 98 | 99 | return () => destroyChart(); 100 | }, []); 101 | 102 | return ( 103 | 110 | {fallbackContent} 111 | 112 | ); 113 | } 114 | 115 | export const Chart = forwardRef(ChartComponent) as BaseChartComponent; 116 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export type { ChartProps } from './types.js'; 2 | export * from './chart.js'; 3 | export * from './typedCharts.js'; 4 | export { 5 | getDatasetAtEvent, 6 | getElementAtEvent, 7 | getElementsAtEvent, 8 | } from './utils.js'; 9 | -------------------------------------------------------------------------------- /src/typedCharts.tsx: -------------------------------------------------------------------------------- 1 | import React, { forwardRef } from 'react'; 2 | import { 3 | Chart as ChartJS, 4 | LineController, 5 | BarController, 6 | RadarController, 7 | DoughnutController, 8 | PolarAreaController, 9 | BubbleController, 10 | PieController, 11 | ScatterController, 12 | } from 'chart.js'; 13 | import type { ChartType, ChartComponentLike } from 'chart.js'; 14 | 15 | import type { 16 | ChartProps, 17 | ChartJSOrUndefined, 18 | TypedChartComponent, 19 | } from './types.js'; 20 | import { Chart } from './chart.js'; 21 | 22 | function createTypedChart( 23 | type: T, 24 | registerables: ChartComponentLike 25 | ) { 26 | ChartJS.register(registerables); 27 | 28 | return forwardRef, Omit, 'type'>>( 29 | (props, ref) => 30 | ) as TypedChartComponent; 31 | } 32 | 33 | export const Line = /* #__PURE__ */ createTypedChart('line', LineController); 34 | 35 | export const Bar = /* #__PURE__ */ createTypedChart('bar', BarController); 36 | 37 | export const Radar = /* #__PURE__ */ createTypedChart('radar', RadarController); 38 | 39 | export const Doughnut = /* #__PURE__ */ createTypedChart( 40 | 'doughnut', 41 | DoughnutController 42 | ); 43 | 44 | export const PolarArea = /* #__PURE__ */ createTypedChart( 45 | 'polarArea', 46 | PolarAreaController 47 | ); 48 | 49 | export const Bubble = /* #__PURE__ */ createTypedChart( 50 | 'bubble', 51 | BubbleController 52 | ); 53 | 54 | export const Pie = /* #__PURE__ */ createTypedChart('pie', PieController); 55 | 56 | export const Scatter = /* #__PURE__ */ createTypedChart( 57 | 'scatter', 58 | ScatterController 59 | ); 60 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import type { CanvasHTMLAttributes, MutableRefObject, ReactNode } from 'react'; 2 | import type { 3 | Chart, 4 | ChartType, 5 | ChartData, 6 | ChartOptions, 7 | DefaultDataPoint, 8 | Plugin, 9 | UpdateMode, 10 | } from 'chart.js'; 11 | 12 | export type ForwardedRef = 13 | | ((instance: T | null) => void) 14 | | MutableRefObject 15 | | null; 16 | 17 | export interface ChartProps< 18 | TType extends ChartType = ChartType, 19 | TData = DefaultDataPoint, 20 | TLabel = unknown 21 | > extends CanvasHTMLAttributes { 22 | /** 23 | * Chart.js chart type 24 | */ 25 | type: TType; 26 | /** 27 | * The data object that is passed into the Chart.js chart 28 | * @see https://www.chartjs.org/docs/latest/getting-started/ 29 | */ 30 | data: ChartData; 31 | /** 32 | * The options object that is passed into the Chart.js chart 33 | * @see https://www.chartjs.org/docs/latest/general/options.html 34 | * @default {} 35 | */ 36 | options?: ChartOptions; 37 | /** 38 | * The plugins array that is passed into the Chart.js chart 39 | * @see https://www.chartjs.org/docs/latest/developers/plugins.html 40 | * @default [] 41 | */ 42 | plugins?: Plugin[]; 43 | /** 44 | * Teardown and redraw chart on every update 45 | * @default false 46 | */ 47 | redraw?: boolean; 48 | /** 49 | * Key name to identificate dataset 50 | * @default 'label' 51 | */ 52 | datasetIdKey?: string; 53 | /** 54 | * A fallback for when the canvas cannot be rendered. Can be used for accessible chart descriptions 55 | * @see https://www.chartjs.org/docs/latest/general/accessibility.html 56 | * @default null 57 | * @todo Replace with `children` prop. 58 | */ 59 | fallbackContent?: ReactNode; 60 | /** 61 | * A mode string to indicate transition configuration should be used. 62 | * @see https://www.chartjs.org/docs/latest/developers/api.html#update-mode 63 | */ 64 | updateMode?: UpdateMode; 65 | } 66 | 67 | /** 68 | * @todo Replace `undefined` with `null` 69 | */ 70 | export type ChartJSOrUndefined< 71 | TType extends ChartType = ChartType, 72 | TData = DefaultDataPoint, 73 | TLabel = unknown 74 | > = Chart | undefined; 75 | 76 | export type BaseChartComponent = < 77 | TType extends ChartType = ChartType, 78 | TData = DefaultDataPoint, 79 | TLabel = unknown 80 | >( 81 | props: ChartProps & { 82 | ref?: ForwardedRef>; 83 | } 84 | ) => JSX.Element; 85 | 86 | export type TypedChartComponent = < 87 | TData = DefaultDataPoint, 88 | TLabel = unknown 89 | >( 90 | props: Omit, 'type'> & { 91 | ref?: ForwardedRef>; 92 | } 93 | ) => JSX.Element; 94 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import type { MouseEvent } from 'react'; 2 | import type { 3 | ChartType, 4 | ChartData, 5 | DefaultDataPoint, 6 | ChartDataset, 7 | ChartOptions, 8 | Chart, 9 | } from 'chart.js'; 10 | 11 | import type { ForwardedRef } from './types.js'; 12 | 13 | const defaultDatasetIdKey = 'label'; 14 | 15 | export function reforwardRef(ref: ForwardedRef, value: T) { 16 | if (typeof ref === 'function') { 17 | ref(value); 18 | } else if (ref) { 19 | ref.current = value; 20 | } 21 | } 22 | 23 | export function setOptions< 24 | TType extends ChartType = ChartType, 25 | TData = DefaultDataPoint, 26 | TLabel = unknown 27 | >(chart: Chart, nextOptions: ChartOptions) { 28 | const options = chart.options; 29 | 30 | if (options && nextOptions) { 31 | Object.assign(options, nextOptions); 32 | } 33 | } 34 | 35 | export function setLabels< 36 | TType extends ChartType = ChartType, 37 | TData = DefaultDataPoint, 38 | TLabel = unknown 39 | >( 40 | currentData: ChartData, 41 | nextLabels: TLabel[] | undefined 42 | ) { 43 | currentData.labels = nextLabels; 44 | } 45 | 46 | export function setDatasets< 47 | TType extends ChartType = ChartType, 48 | TData = DefaultDataPoint, 49 | TLabel = unknown 50 | >( 51 | currentData: ChartData, 52 | nextDatasets: ChartDataset[], 53 | datasetIdKey = defaultDatasetIdKey 54 | ) { 55 | const addedDatasets: ChartDataset[] = []; 56 | 57 | currentData.datasets = nextDatasets.map( 58 | (nextDataset: Record) => { 59 | // given the new set, find it's current match 60 | const currentDataset = currentData.datasets.find( 61 | (dataset: Record) => 62 | dataset[datasetIdKey] === nextDataset[datasetIdKey] 63 | ); 64 | 65 | // There is no original to update, so simply add new one 66 | if ( 67 | !currentDataset || 68 | !nextDataset.data || 69 | addedDatasets.includes(currentDataset) 70 | ) { 71 | return { ...nextDataset } as ChartDataset; 72 | } 73 | 74 | addedDatasets.push(currentDataset); 75 | 76 | Object.assign(currentDataset, nextDataset); 77 | 78 | return currentDataset; 79 | } 80 | ); 81 | } 82 | 83 | export function cloneData< 84 | TType extends ChartType = ChartType, 85 | TData = DefaultDataPoint, 86 | TLabel = unknown 87 | >(data: ChartData, datasetIdKey = defaultDatasetIdKey) { 88 | const nextData: ChartData = { 89 | labels: [], 90 | datasets: [], 91 | }; 92 | 93 | setLabels(nextData, data.labels); 94 | setDatasets(nextData, data.datasets, datasetIdKey); 95 | 96 | return nextData; 97 | } 98 | 99 | /** 100 | * Get dataset from mouse click event 101 | * @param chart - Chart.js instance 102 | * @param event - Mouse click event 103 | * @returns Dataset 104 | */ 105 | export function getDatasetAtEvent( 106 | chart: Chart, 107 | event: MouseEvent 108 | ) { 109 | return chart.getElementsAtEventForMode( 110 | event.nativeEvent, 111 | 'dataset', 112 | { intersect: true }, 113 | false 114 | ); 115 | } 116 | 117 | /** 118 | * Get single dataset element from mouse click event 119 | * @param chart - Chart.js instance 120 | * @param event - Mouse click event 121 | * @returns Dataset 122 | */ 123 | export function getElementAtEvent( 124 | chart: Chart, 125 | event: MouseEvent 126 | ) { 127 | return chart.getElementsAtEventForMode( 128 | event.nativeEvent, 129 | 'nearest', 130 | { intersect: true }, 131 | false 132 | ); 133 | } 134 | 135 | /** 136 | * Get all dataset elements from mouse click event 137 | * @param chart - Chart.js instance 138 | * @param event - Mouse click event 139 | * @returns Dataset 140 | */ 141 | export function getElementsAtEvent( 142 | chart: Chart, 143 | event: MouseEvent 144 | ) { 145 | return chart.getElementsAtEventForMode( 146 | event.nativeEvent, 147 | 'index', 148 | { intersect: true }, 149 | false 150 | ); 151 | } 152 | -------------------------------------------------------------------------------- /stories/Bar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import 'chart.js/auto'; 3 | import { Bar } from '../src'; 4 | import * as verticalBar from '../sandboxes/bar/vertical/App'; 5 | import * as horizontalBar from '../sandboxes/bar/horizontal/App'; 6 | import * as stackedBar from '../sandboxes/bar/stacked/App'; 7 | import * as groupedBar from '../sandboxes/bar/grouped/App'; 8 | 9 | export default { 10 | title: 'Components/Bar', 11 | component: Bar, 12 | parameters: { 13 | layout: 'centered', 14 | }, 15 | args: { 16 | width: 500, 17 | height: 400, 18 | }, 19 | }; 20 | 21 | export const Vertical = args => ; 22 | 23 | Vertical.args = { 24 | data: verticalBar.data, 25 | options: verticalBar.options, 26 | }; 27 | 28 | export const Horizontal = args => ; 29 | 30 | Horizontal.args = { 31 | data: horizontalBar.data, 32 | options: horizontalBar.options, 33 | }; 34 | 35 | export const Stacked = args => ; 36 | 37 | Stacked.args = { 38 | data: stackedBar.data, 39 | options: stackedBar.options, 40 | }; 41 | 42 | export const Grouped = args => ; 43 | 44 | Grouped.args = { 45 | data: groupedBar.data, 46 | options: groupedBar.options, 47 | }; 48 | -------------------------------------------------------------------------------- /stories/Bubble.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import 'chart.js/auto'; 3 | import { Bubble } from '../src'; 4 | import { data, options } from '../sandboxes/bubble/default/App'; 5 | 6 | export default { 7 | title: 'Components/Bubble', 8 | component: Bubble, 9 | parameters: { 10 | layout: 'centered', 11 | }, 12 | args: { 13 | width: 500, 14 | height: 400, 15 | }, 16 | }; 17 | 18 | export const Default = args => ; 19 | 20 | Default.args = { 21 | data, 22 | options, 23 | }; 24 | -------------------------------------------------------------------------------- /stories/Chart.data.ts: -------------------------------------------------------------------------------- 1 | import faker from 'faker'; 2 | import { colorRed } from './data'; 3 | 4 | export const dynamicOptions = { 5 | scales: { 6 | y: { 7 | beginAtZero: true, 8 | }, 9 | }, 10 | }; 11 | 12 | export const getDynamicData = () => ({ 13 | labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], 14 | datasets: [ 15 | { 16 | type: 'bar', 17 | label: 'Scale', 18 | data: Array.from({ length: 6 }, () => 19 | faker.datatype.number({ min: -10, max: 10 }) 20 | ), 21 | backgroundColor: [ 22 | 'rgba(255, 99, 132, 0.2)', 23 | 'rgba(54, 162, 235, 0.2)', 24 | 'rgba(255, 206, 86, 0.2)', 25 | 'rgba(75, 192, 192, 0.2)', 26 | 'rgba(153, 102, 255, 0.2)', 27 | 'rgba(255, 159, 64, 0.2)', 28 | ], 29 | borderColor: [ 30 | 'rgba(255, 99, 132, 1)', 31 | 'rgba(54, 162, 235, 1)', 32 | 'rgba(255, 206, 86, 1)', 33 | 'rgba(75, 192, 192, 1)', 34 | 'rgba(153, 102, 255, 1)', 35 | 'rgba(255, 159, 64, 1)', 36 | ], 37 | borderWidth: 1, 38 | }, 39 | ], 40 | }); 41 | 42 | export const sameData1 = { 43 | labels: [ 44 | 'Jan', 45 | 'Feb', 46 | 'Mar', 47 | 'Apr', 48 | 'Mei', 49 | 'Jun', 50 | 'Jul', 51 | 'Aug', 52 | 'Sep', 53 | 'Oct', 54 | 'Nov', 55 | 'Dec', 56 | ], 57 | datasets: [ 58 | { 59 | label: 'My First dataset', 60 | backgroundColor: 'rgba(75,192,192,0.4)', 61 | data: [33, 53, 85, 41, 44, 65, 61, 47, 52, 53, 62, 82], 62 | }, 63 | { 64 | label: 'My Second dataset', 65 | backgroundColor: '#742774', 66 | data: [33, 25, 35, 51, 54, 76, 65, 40, 42, 39, 51, 55], 67 | }, 68 | ], 69 | }; 70 | 71 | export const sameData2 = { 72 | labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], 73 | datasets: [ 74 | { 75 | label: 'My First dataset', 76 | backgroundColor: 'rgba(75,192,192,0.4)', 77 | data: [42, 13, 45, 29, 44, 25, 27], 78 | }, 79 | { 80 | label: 'My Second dataset', 81 | backgroundColor: '#742774', 82 | data: [33, 25, 35, 44, 50, 40, 48], 83 | }, 84 | ], 85 | }; 86 | 87 | export const decimationOptions = { 88 | // Turn off animations and data parsing for performance 89 | animation: false, 90 | parsing: false, 91 | 92 | interaction: { 93 | mode: 'nearest', 94 | axis: 'x', 95 | intersect: false, 96 | }, 97 | plugins: { 98 | decimation: { 99 | enabled: true, 100 | algorithm: 'lttb', 101 | samples: 500, 102 | }, 103 | }, 104 | scales: { 105 | x: { 106 | type: 'time', 107 | ticks: { 108 | source: 'auto', 109 | // Disabled rotation for performance 110 | maxRotation: 0, 111 | autoSkip: true, 112 | }, 113 | }, 114 | }, 115 | }; 116 | 117 | export const getDecimationData = () => { 118 | const start = Date.now(); 119 | const data = Array.from({ length: 100000 }, (_, i) => ({ 120 | x: start + i * 30000, 121 | y: faker.datatype.number({ min: 0, max: Math.random() < 0.001 ? 100 : 20 }), 122 | })); 123 | 124 | return { 125 | datasets: [ 126 | { 127 | borderColor: colorRed, 128 | borderWidth: 1, 129 | data, 130 | label: 'Large Dataset', 131 | radius: 0, 132 | }, 133 | ], 134 | }; 135 | }; 136 | -------------------------------------------------------------------------------- /stories/Chart.tsx: -------------------------------------------------------------------------------- 1 | import React, { 2 | MouseEvent, 3 | useRef, 4 | useState, 5 | useEffect, 6 | useReducer, 7 | useMemo, 8 | } from 'react'; 9 | import 'chart.js/auto'; 10 | import type { InteractionItem } from 'chart.js'; 11 | import { Chart as ChartJS } from 'chart.js'; 12 | import 'chartjs-adapter-date-fns'; 13 | import annotationPlugin from 'chartjs-plugin-annotation'; 14 | import zoomPlugin from 'chartjs-plugin-zoom'; 15 | import { 16 | Chart, 17 | getDatasetAtEvent, 18 | getElementAtEvent, 19 | getElementsAtEvent, 20 | } from '../src'; 21 | import * as multitypeChart from '../sandboxes/chart/multitype/App'; 22 | import * as eventsChart from '../sandboxes/chart/events/App'; 23 | import * as data from './Chart.data'; 24 | 25 | ChartJS.register(annotationPlugin, zoomPlugin); 26 | 27 | export default { 28 | title: 'Components/Chart', 29 | component: Chart, 30 | parameters: { 31 | layout: 'centered', 32 | }, 33 | args: { 34 | width: 500, 35 | height: 400, 36 | }, 37 | }; 38 | 39 | export const MultiType = args => ; 40 | 41 | MultiType.args = { 42 | data: multitypeChart.data, 43 | }; 44 | 45 | export const Dynamic = args => { 46 | const [dynamicData, setDynamicData] = useState(data.getDynamicData); 47 | 48 | useEffect(() => { 49 | const interval = setInterval( 50 | () => setDynamicData(data.getDynamicData()), 51 | 3000 52 | ); 53 | 54 | return () => clearInterval(interval); 55 | }, []); 56 | 57 | return ; 58 | }; 59 | 60 | Dynamic.args = { 61 | options: data.dynamicOptions, 62 | }; 63 | 64 | export const ClickEvents = ({ 65 | onDatasetClick, 66 | onElementClick, 67 | onElementsClick, 68 | options, 69 | data, 70 | ...args 71 | }) => { 72 | const datasetAtEvent = (dataset: InteractionItem[]) => { 73 | if (!dataset.length) return; 74 | 75 | const datasetIndex = dataset[0].datasetIndex; 76 | 77 | onDatasetClick(data.datasets[datasetIndex].label); 78 | }; 79 | 80 | const elementAtEvent = (element: InteractionItem[]) => { 81 | if (!element.length) return; 82 | 83 | const { datasetIndex, index } = element[0]; 84 | 85 | onElementClick(data.labels[index], data.datasets[datasetIndex].data[index]); 86 | }; 87 | 88 | const elementsAtEvent = (elements: InteractionItem[]) => { 89 | if (!elements.length) return; 90 | 91 | onElementsClick(elements); 92 | }; 93 | 94 | const chartRef = useRef(null); 95 | 96 | const onClick = (event: MouseEvent) => { 97 | const { current: chart } = chartRef; 98 | 99 | if (!chart) { 100 | return; 101 | } 102 | 103 | datasetAtEvent(getDatasetAtEvent(chart, event)); 104 | elementAtEvent(getElementAtEvent(chart, event)); 105 | elementsAtEvent(getElementsAtEvent(chart, event)); 106 | }; 107 | 108 | return ( 109 | 117 | ); 118 | }; 119 | 120 | ClickEvents.args = { 121 | options: eventsChart.options, 122 | data: eventsChart.data, 123 | }; 124 | 125 | ClickEvents.argTypes = { 126 | onDatasetClick: { action: 'dataset clicked' }, 127 | onElementClick: { action: 'element clicked' }, 128 | onElementsClick: { action: 'elements clicked' }, 129 | }; 130 | 131 | export const Redraw = args => ; 132 | 133 | Redraw.args = { 134 | data: multitypeChart.data, 135 | redraw: true, 136 | }; 137 | 138 | export const SameDataToggle = args => { 139 | const [currentData, toggleData] = useReducer( 140 | prevState => 141 | prevState === data.sameData1 ? data.sameData2 : data.sameData1, 142 | data.sameData1 143 | ); 144 | 145 | return ; 146 | }; 147 | 148 | SameDataToggle.args = { 149 | type: 'bar', 150 | }; 151 | 152 | export const Decimation = args => { 153 | const [currentData, toggleData] = useReducer( 154 | data.getDecimationData, 155 | data.getDecimationData() 156 | ); 157 | 158 | return ; 159 | }; 160 | 161 | Decimation.args = { 162 | type: 'line', 163 | options: data.decimationOptions, 164 | }; 165 | 166 | export const DynamicOptions = args => { 167 | const [yMax, setYMax] = useState(100); 168 | const options = useMemo( 169 | () => ({ 170 | plugins: { 171 | annotation: { 172 | annotations: { 173 | box1: { 174 | type: 'box', 175 | xMin: 1, 176 | xMax: 2, 177 | yMin: 50, 178 | yMax: yMax, 179 | backgroundColor: 'rgba(255, 99, 132, 0.25)', 180 | }, 181 | }, 182 | }, 183 | zoom: { 184 | zoom: { 185 | wheel: { 186 | enabled: true, 187 | }, 188 | pinch: { 189 | enabled: true, 190 | }, 191 | mode: 'xy', 192 | }, 193 | }, 194 | }, 195 | }), 196 | [yMax] 197 | ); 198 | 199 | return ( 200 | <> 201 | 202 | 203 | 204 | ); 205 | }; 206 | 207 | DynamicOptions.args = { 208 | data: multitypeChart.data, 209 | }; 210 | -------------------------------------------------------------------------------- /stories/Doughnut.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import 'chart.js/auto'; 3 | import { Doughnut } from '../src'; 4 | import { data } from '../sandboxes/doughnut/default/App'; 5 | 6 | export default { 7 | title: 'Components/Doughnut', 8 | component: Doughnut, 9 | parameters: { 10 | layout: 'centered', 11 | }, 12 | args: { 13 | width: 500, 14 | height: 400, 15 | }, 16 | }; 17 | 18 | export const Default = args => ; 19 | 20 | Default.args = { 21 | data, 22 | }; 23 | 24 | export const Rotation = args => { 25 | const [rotation, setRotation] = useState(0); 26 | 27 | useEffect(() => { 28 | const interval = setInterval(() => { 29 | setRotation(rotation => rotation + 90); 30 | }, 3000); 31 | 32 | return () => clearInterval(interval); 33 | }); 34 | 35 | return ; 36 | }; 37 | 38 | Rotation.args = { 39 | data, 40 | }; 41 | -------------------------------------------------------------------------------- /stories/Line.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import 'chart.js/auto'; 3 | import { Line } from '../src'; 4 | import * as defaultLine from '../sandboxes/line/default/App'; 5 | import * as multiaxisLine from '../sandboxes/line/multiaxis/App'; 6 | 7 | export default { 8 | title: 'Components/Line', 9 | component: Line, 10 | parameters: { 11 | layout: 'centered', 12 | }, 13 | args: { 14 | width: 500, 15 | height: 400, 16 | }, 17 | }; 18 | 19 | export const Default = args => ; 20 | 21 | Default.args = { 22 | data: defaultLine.data, 23 | options: defaultLine.options, 24 | }; 25 | 26 | export const MultiAxis = args => ; 27 | 28 | MultiAxis.args = { 29 | data: multiaxisLine.data, 30 | options: multiaxisLine.options, 31 | }; 32 | -------------------------------------------------------------------------------- /stories/Pie.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import faker from 'faker'; 3 | import 'chart.js/auto'; 4 | import { Pie } from '../src'; 5 | import { data } from '../sandboxes/pie/default/App'; 6 | 7 | export default { 8 | title: 'Components/Pie', 9 | component: Pie, 10 | parameters: { 11 | layout: 'centered', 12 | }, 13 | args: { 14 | width: 500, 15 | height: 400, 16 | }, 17 | }; 18 | 19 | export const Default = args => ; 20 | 21 | Default.args = { 22 | data, 23 | }; 24 | 25 | function randomDataset() { 26 | return { 27 | value: faker.datatype.number({ min: -100, max: 100 }), 28 | color: faker.internet.color(), 29 | }; 30 | } 31 | 32 | export const Dynamic = args => { 33 | const [datasets, setDatasets] = useState(() => [randomDataset()]); 34 | const onAdd = () => { 35 | setDatasets(datasets => [...datasets, randomDataset()]); 36 | }; 37 | const onRemove = () => { 38 | setDatasets(datasets => datasets.slice(0, -1)); 39 | }; 40 | const data = { 41 | labels: datasets.map((_, i) => `#${i}`), 42 | datasets: [ 43 | { 44 | data: datasets.map(({ value }) => value), 45 | backgroundColor: datasets.map(({ color }) => color), 46 | }, 47 | ], 48 | }; 49 | 50 | return ( 51 | <> 52 | 53 | 54 | 55 |
    56 | {datasets.map(({ value, color }, i) => ( 57 |
  • 58 | {value} 59 |
  • 60 | ))} 61 |
62 | 63 | ); 64 | }; 65 | -------------------------------------------------------------------------------- /stories/PolarArea.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import 'chart.js/auto'; 3 | import { PolarArea } from '../src'; 4 | import { data } from '../sandboxes/polarArea/default/App'; 5 | 6 | export default { 7 | title: 'Components/PolarArea', 8 | component: PolarArea, 9 | parameters: { 10 | layout: 'centered', 11 | }, 12 | args: { 13 | width: 500, 14 | height: 400, 15 | }, 16 | }; 17 | 18 | export const Default = args => ; 19 | 20 | Default.args = { 21 | data, 22 | }; 23 | -------------------------------------------------------------------------------- /stories/Radar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import 'chart.js/auto'; 3 | import { Radar } from '../src'; 4 | import { data } from '../sandboxes/radar/default/App'; 5 | 6 | export default { 7 | title: 'Components/Radar', 8 | component: Radar, 9 | parameters: { 10 | layout: 'centered', 11 | }, 12 | args: { 13 | width: 500, 14 | height: 400, 15 | }, 16 | }; 17 | 18 | export const Default = args => ; 19 | 20 | Default.args = { 21 | data, 22 | }; 23 | -------------------------------------------------------------------------------- /stories/Scatter.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import 'chart.js/auto'; 3 | import { Scatter } from '../src'; 4 | import { data, options } from '../sandboxes/scatter/default/App'; 5 | 6 | export default { 7 | title: 'Components/Scatter', 8 | component: Scatter, 9 | parameters: { 10 | layout: 'centered', 11 | }, 12 | args: { 13 | width: 500, 14 | height: 400, 15 | }, 16 | }; 17 | 18 | export const Default = args => ; 19 | 20 | Default.args = { 21 | data, 22 | options, 23 | }; 24 | -------------------------------------------------------------------------------- /stories/data.ts: -------------------------------------------------------------------------------- 1 | import faker from 'faker'; 2 | 3 | export const months = [ 4 | 'January', 5 | 'February', 6 | 'March', 7 | 'April', 8 | 'May', 9 | 'June', 10 | 'July', 11 | ]; 12 | export const colorRed = 'rgb(255, 99, 132)'; 13 | export const colorRed05 = 'rgba(255, 99, 132, 0.5)'; 14 | export const colorGreen = 'rgb(75, 192, 192)'; 15 | export const colorGreen05 = 'rgba(75, 192, 192, 0.5)'; 16 | export const colorBlue = 'rgb(53, 162, 235)'; 17 | export const colorBlue05 = 'rgba(53, 162, 235, 0.5)'; 18 | 19 | export function numbers(count = months.length) { 20 | return Array.from({ length: count }, () => 21 | faker.datatype.number({ min: -100, max: 100 }) 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /test/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "@typescript-eslint/no-explicit-any": "off" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/chart.test-d.tsx: -------------------------------------------------------------------------------- 1 | import { expectError } from 'tsd'; 2 | import React from 'react'; 3 | import type { Plugin } from 'chart.js'; 4 | import { Chart, Scatter, Doughnut } from '../src'; 5 | 6 | const data = { 7 | datasets: [], 8 | }; 9 | const multiTypeData = { 10 | datasets: [ 11 | { 12 | type: 'line' as const, 13 | label: 'Dataset 1', 14 | data: [], 15 | }, 16 | { 17 | type: 'bar' as const, 18 | label: 'Dataset 2', 19 | data: [], 20 | }, 21 | ], 22 | }; 23 | 24 | /** 25 | * Should check type-specific props 26 | */ 27 | 28 | []} />; 29 | []} />; 30 | ; 31 | []} />; 32 | 33 | expectError([]} />); 34 | 35 | /** 36 | * Should check type-specific options 37 | */ 38 | 39 | ; 45 | 46 | expectError( 47 | 53 | ); 54 | -------------------------------------------------------------------------------- /test/chart.test.tsx: -------------------------------------------------------------------------------- 1 | import { vi, beforeEach, afterEach, describe, it, expect } from 'vitest'; 2 | import React from 'react'; 3 | import { render, cleanup, fireEvent } from '@testing-library/react'; 4 | import 'chart.js/auto'; 5 | import { Chart as ChartJS } from 'chart.js'; 6 | import { Chart } from '../src/index.js'; 7 | 8 | describe('', () => { 9 | const data = { 10 | labels: ['red', 'blue'], 11 | datasets: [{ label: 'colors', data: [1, 2] }], 12 | }; 13 | 14 | const options = { 15 | responsive: false, 16 | }; 17 | 18 | let chart: any, update: any, destroy: any; 19 | const ref = (el: ChartJS | undefined | null): void => { 20 | chart = el; 21 | 22 | if (chart) { 23 | update = vi.spyOn(chart, 'update'); 24 | destroy = vi.spyOn(chart, 'destroy'); 25 | } 26 | }; 27 | 28 | beforeEach(() => { 29 | chart = null; 30 | }); 31 | 32 | afterEach(() => { 33 | if (chart) chart.destroy(); 34 | 35 | cleanup(); 36 | 37 | if (update) update.mockClear(); 38 | if (destroy) destroy.mockClear(); 39 | }); 40 | 41 | it('should not pollute props', () => { 42 | render(); 43 | 44 | expect(data).toStrictEqual({ 45 | labels: ['red', 'blue'], 46 | datasets: [{ label: 'colors', data: [1, 2] }], 47 | }); 48 | 49 | // expect(options).toStrictEqual({ 50 | // responsive: false, 51 | // }); 52 | }); 53 | 54 | it('should set ref to chart instance', () => { 55 | render(); 56 | 57 | expect(chart).toBeTruthy(); 58 | expect(chart instanceof ChartJS).toBe(true); 59 | }); 60 | 61 | it('should pass props onto chart', () => { 62 | render(); 63 | 64 | expect(chart.config.data).toMatchObject(data); 65 | expect(chart.config.options).toMatchObject(options); 66 | expect(chart.config.type).toEqual('bar'); 67 | }); 68 | 69 | it('should pass new data on data change', () => { 70 | const newData = { 71 | labels: ['red', 'blue'], 72 | datasets: [{ label: 'colors', data: [2, 1] }], 73 | }; 74 | 75 | const { rerender } = render( 76 | 77 | ); 78 | 79 | // const meta = chart.config.data.datasets[0]._meta; 80 | const id = chart.id; 81 | 82 | rerender(); 83 | 84 | expect(chart.config.data).toMatchObject(newData); 85 | // make sure that other properties were maintained 86 | // expect(chart.config.data.datasets[0]._meta).toEqual(meta); 87 | expect(update).toHaveBeenCalled(); 88 | expect(chart.id).toEqual(id); 89 | }); 90 | 91 | it('should properly update with entirely new data', () => { 92 | const newData = { 93 | labels: ['purple', 'pink'], 94 | datasets: [{ label: 'new-colors', data: [1, 10] }], 95 | }; 96 | 97 | const { rerender } = render( 98 | 99 | ); 100 | 101 | const meta = chart.config.data.datasets[0]._meta; 102 | const id = chart.id; 103 | 104 | rerender(); 105 | 106 | expect(chart.config.data).toMatchObject(newData); 107 | expect(meta).not.toEqual(chart.config.data.datasets[0]); 108 | expect(update).toHaveBeenCalled(); 109 | expect(chart.id).toEqual(id); 110 | }); 111 | 112 | it('should properly update with a new chart type', () => { 113 | const newType = 'line'; 114 | 115 | const { rerender } = render( 116 | 117 | ); 118 | 119 | const originalChartDestroy = destroy; 120 | 121 | rerender(); 122 | 123 | expect(originalChartDestroy).toHaveBeenCalled(); 124 | }); 125 | 126 | it('should properly maintain order with new data', () => { 127 | const oldData = { 128 | labels: ['red', 'blue'], 129 | datasets: [ 130 | { label: 'new-colors', data: [1, 2] }, 131 | { label: 'colors', data: [3, 2] }, 132 | ], 133 | }; 134 | 135 | const newData = { 136 | labels: ['red', 'blue'], 137 | datasets: [ 138 | { label: 'colors', data: [4, 5] }, 139 | { label: 'new-colors', data: [1, 2] }, 140 | ], 141 | }; 142 | 143 | const { rerender } = render( 144 | 145 | ); 146 | 147 | const meta = Object.assign({}, chart._metasets); 148 | 149 | const id = chart.id; 150 | 151 | rerender(); 152 | 153 | expect(chart.config.data).toMatchObject(newData); 154 | expect(meta[0]).toBe(chart._metasets[1]); 155 | expect(meta[1]).toBe(chart._metasets[0]); 156 | expect(update).toHaveBeenCalled(); 157 | expect(chart.id).toEqual(id); 158 | }); 159 | 160 | it('should properly update when original data did not exist', () => { 161 | const oldData = { 162 | labels: ['red', 'blue'], 163 | datasets: [ 164 | { label: 'new-colors', data: [] }, 165 | { label: 'colors', data: [3, 2] }, 166 | ], 167 | }; 168 | 169 | const newData = { 170 | labels: ['red', 'blue'], 171 | datasets: [ 172 | { label: 'colors', data: [4, 5] }, 173 | { label: 'new-colors', data: [1, 2] }, 174 | ], 175 | }; 176 | 177 | const { rerender } = render( 178 | 179 | ); 180 | 181 | // even when we feed the data as undefined, the constructor will 182 | // force it to []. Here we force it back 183 | chart.config.data.datasets[0].data = undefined; 184 | const meta = Object.assign({}, chart._metasets); 185 | 186 | const id = chart.id; 187 | 188 | rerender(); 189 | 190 | expect(chart.config.data).toMatchObject(newData); 191 | expect(meta[0]).toBe(chart._metasets[1]); 192 | expect(update).toHaveBeenCalled(); 193 | expect(chart.id).toEqual(id); 194 | }); 195 | 196 | it('should properly update when incoming data does not exist', () => { 197 | const oldData = { 198 | labels: ['red', 'blue'], 199 | datasets: [ 200 | { label: 'new-colors', data: [1, 2] }, 201 | { label: 'colors', data: [3, 2] }, 202 | ], 203 | }; 204 | 205 | const newData = { 206 | labels: ['red', 'blue'], 207 | datasets: [ 208 | { label: 'colors', data: [4, 5] }, 209 | { label: 'new-colors', data: [] }, 210 | ], 211 | }; 212 | 213 | const { rerender } = render( 214 | 215 | ); 216 | 217 | const id = chart.id; 218 | 219 | rerender(); 220 | 221 | expect(chart.config.data).toMatchObject(newData); 222 | expect(update).toHaveBeenCalled(); 223 | expect(chart.id).toEqual(id); 224 | }); 225 | 226 | it('should pass new options on options change', () => { 227 | const newOptions = { 228 | responsive: true, 229 | }; 230 | 231 | const { rerender } = render( 232 | 233 | ); 234 | 235 | const id = chart.id; 236 | 237 | rerender(); 238 | 239 | expect(chart.options).toMatchObject(newOptions); 240 | expect(update).toHaveBeenCalled(); 241 | expect(chart.id).toEqual(id); 242 | }); 243 | 244 | it('should destroy and rerender when set to redraw', () => { 245 | const newData = { 246 | labels: ['red', 'blue'], 247 | datasets: [{ label: 'colors', data: [2, 1] }], 248 | }; 249 | 250 | const { rerender } = render( 251 | 252 | ); 253 | 254 | // const id = chart.id; 255 | const originalChartDestroy = destroy; 256 | 257 | rerender( 258 | 259 | ); 260 | 261 | expect(originalChartDestroy).toHaveBeenCalled(); 262 | }); 263 | 264 | it('should destroy when unmounted', () => { 265 | const { unmount } = render( 266 | 267 | ); 268 | 269 | expect(chart).toBeTruthy(); 270 | 271 | unmount(); 272 | 273 | expect(chart).toBe(null); 274 | }); 275 | 276 | it('should add className ', () => { 277 | render( 278 | 285 | ); 286 | 287 | expect(chart).toBeTruthy(); 288 | expect(chart.canvas).toHaveProperty('className'); 289 | expect(chart.canvas).toHaveClass('chart-example'); 290 | }); 291 | 292 | it('should call onClick', () => { 293 | const onClick = vi.fn(); 294 | 295 | const { getByTestId } = render( 296 | 304 | ); 305 | 306 | fireEvent.click(getByTestId('canvas')); 307 | 308 | expect(onClick).toHaveBeenCalled(); 309 | }); 310 | 311 | it('should show fallback content if given', () => { 312 | const fallback =

Fallback content

; 313 | const { getByTestId } = render( 314 | 322 | ); 323 | 324 | expect(chart).toBeTruthy(); 325 | expect(chart.canvas).toContainElement(getByTestId('fallbackContent')); 326 | }); 327 | 328 | it('should pass through aria labels to the canvas element', () => { 329 | const ariaLabel = 'ARIA LABEL'; 330 | render( 331 | 338 | ); 339 | 340 | expect(chart.canvas.getAttribute('aria-label')).toBe(ariaLabel); 341 | }); 342 | 343 | it('should rerender datasets with same labels', () => { 344 | const getData = () => ({ 345 | labels: [1, 2, 3], 346 | datasets: [ 347 | { 348 | label: '', 349 | data: [5, 6, 7], 350 | }, 351 | { 352 | label: '', 353 | data: [3, 2, 1], 354 | }, 355 | ], 356 | }); 357 | 358 | const { rerender } = render( 359 | 360 | ); 361 | 362 | const [prevDataset1, prevDataset2] = chart.config.data.datasets; 363 | 364 | rerender(); 365 | 366 | const [nextDataset1, nextDataset2] = chart.config.data.datasets; 367 | 368 | expect(prevDataset1).toBe(nextDataset1); 369 | expect(prevDataset2).not.toBe(nextDataset2); 370 | }); 371 | 372 | it('should rerender datasets with id', () => { 373 | const getData = () => ({ 374 | labels: [1, 2, 3], 375 | datasets: [ 376 | { 377 | id: 1, 378 | label: '', 379 | data: [5, 6, 7], 380 | }, 381 | { 382 | id: 2, 383 | label: '', 384 | data: [3, 2, 1], 385 | }, 386 | ], 387 | }); 388 | 389 | const { rerender } = render( 390 | 391 | ); 392 | 393 | const [prevDataset1, prevDataset2] = chart.config.data.datasets; 394 | 395 | rerender( 396 | 397 | ); 398 | 399 | const [nextDataset1, nextDataset2] = chart.config.data.datasets; 400 | 401 | expect(prevDataset1).toBe(nextDataset1); 402 | expect(prevDataset2).toBe(nextDataset2); 403 | }); 404 | 405 | it('should pass updateMode prop to update method', () => { 406 | const newData = { 407 | labels: ['purple', 'pink'], 408 | datasets: [{ label: 'new-colors', data: [1, 10] }], 409 | }; 410 | 411 | const { rerender } = render( 412 | 419 | ); 420 | 421 | rerender( 422 | 429 | ); 430 | 431 | expect(update).toHaveBeenCalledTimes(1); 432 | expect(update).toBeCalledWith('active'); 433 | }); 434 | }); 435 | -------------------------------------------------------------------------------- /test/setup.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import matchers from '@testing-library/jest-dom/matchers'; 3 | import { expect } from 'vitest'; 4 | import 'vitest-canvas-mock'; 5 | 6 | expect.extend(matchers); 7 | 8 | class ResizeObserver { 9 | observe() {} 10 | unobserve() {} 11 | disconnect() {} 12 | } 13 | 14 | window.ResizeObserver = ResizeObserver; 15 | 16 | class MutationObserver { 17 | disconnect() {} 18 | unobserve() {} 19 | observe() {} 20 | } 21 | 22 | window.MutationObserver = MutationObserver; 23 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Type Checking */ 4 | "strict": true, 5 | "strictBindCallApply": true, 6 | "noFallthroughCasesInSwitch": true, 7 | "noImplicitOverride": true, 8 | "noImplicitReturns": true, 9 | "noUnusedLocals": true, 10 | "noUnusedParameters": true, 11 | /* Modules */ 12 | "baseUrl": ".", 13 | "module": "ESNext", 14 | "moduleResolution": "NodeNext", 15 | "resolveJsonModule": true, 16 | /* Emit */ 17 | "declaration": true, 18 | "declarationMap": true, 19 | "importsNotUsedAsValues": "error", 20 | "inlineSourceMap": true, 21 | "outDir": "dist", 22 | /* Interop Constraints */ 23 | "allowSyntheticDefaultImports": true, 24 | "isolatedModules": true, 25 | /* Language and Environment */ 26 | "jsx": "react", 27 | "lib": [ 28 | "dom", 29 | "esnext" 30 | ], 31 | "target": "ESNext", 32 | /* Completeness */ 33 | "skipLibCheck": true 34 | }, 35 | "include": [ 36 | "src" 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | test: { 7 | environment: 'jsdom', 8 | setupFiles: ['test/setup.js'], 9 | deps: { 10 | inline: ['vitest-canvas-mock'], 11 | }, 12 | coverage: { 13 | reporter: ['lcovonly', 'text'], 14 | }, 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.* 14 | 15 | npm-debug.log* 16 | -------------------------------------------------------------------------------- /website/CNAME: -------------------------------------------------------------------------------- 1 | react-chartjs-2.js.org 2 | -------------------------------------------------------------------------------- /website/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 4 | 5 | ### Installation 6 | 7 | ``` 8 | $ pnpm install 9 | ``` 10 | 11 | ### Local Development 12 | 13 | ``` 14 | $ pnpm start 15 | ``` 16 | 17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 18 | 19 | ### Build 20 | 21 | ``` 22 | $ pnpm build 23 | ``` 24 | 25 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 26 | 27 | ### Deployment 28 | 29 | ``` 30 | $ GIT_USER= USE_SSH=true pnpm deploy 31 | ``` 32 | 33 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 34 | -------------------------------------------------------------------------------- /website/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /website/docs/chartjs-v2.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /docs/chartjs-v2 3 | description: Using react-chartjs-2 with Chart.js v2 4 | --- 5 | 6 | import Tabs from '@theme/Tabs'; 7 | import TabItem from '@theme/TabItem'; 8 | 9 | # Using with Chart.js v2 10 | 11 | If your app needs [Chart.js v2](https://www.chartjs.org/docs/2.9.4/), please use a [compatible version](https://www.npmjs.com/package/react-chartjs-2/v/2.11.2) of this library: 12 | 13 | 14 | 15 | 16 | ```bash 17 | yarn add chart.js@^2.9.4 react-chartjs-2@^2.11.2 18 | ``` 19 | 20 | 21 | 22 | 23 | ```bash 24 | pnpm add chart.js@^2.9.4 react-chartjs-2@^2.11.2 25 | ``` 26 | 27 | 28 | 29 | 30 | ```bash 31 | npm install --save chart.js@^2.9.4 react-chartjs-2@^2.11.2 32 | ``` 33 | 34 | 35 | 36 | 37 | Also, please consider upgrading your app to [Chart.js v3](#upgrading-to-chartjs-v3). 38 | 39 | ## Upgrading to Chart.js v3 40 | 41 | First, upgrade packages. You'll need to install Chart.js v3 and the latest version of this library: 42 | 43 | 44 | 45 | 46 | ```bash 47 | yarn add chart.js@^3.6.0 react-chartjs-2@^4.0.0 48 | ``` 49 | 50 | 51 | 52 | 53 | ```bash 54 | pnpm add chart.js@^3.6.0 react-chartjs-2@^4.0.0 55 | ``` 56 | 57 | 58 | 59 | 60 | ```bash 61 | npm install --save chart.js@^3.6.0 react-chartjs-2@^4.0.0 62 | ``` 63 | 64 | 65 | 66 | 67 | Then, please follow the [this guide](/docs/migration-to-v4). 68 | -------------------------------------------------------------------------------- /website/docs/chartjs-v3.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /docs/chartjs-v3 3 | description: Using react-chartjs-2 with Chart.js v3 4 | --- 5 | 6 | import Tabs from '@theme/Tabs'; 7 | import TabItem from '@theme/TabItem'; 8 | 9 | # Using with Chart.js v3 10 | 11 | If your app needs [Chart.js v3](https://www.chartjs.org/docs/3.9.1/), please use a [compatible version](https://www.npmjs.com/package/react-chartjs-2/v/4.3.1) of this library: 12 | 13 | 14 | 15 | 16 | ```bash 17 | yarn add chart.js@^3.9.1 react-chartjs-2@^4.3.1 18 | ``` 19 | 20 | 21 | 22 | 23 | ```bash 24 | pnpm add chart.js@^3.9.1 react-chartjs-2@^4.3.1 25 | ``` 26 | 27 | 28 | 29 | 30 | ```bash 31 | npm install --save chart.js@^3.9.1 react-chartjs-2@^4.3.1 32 | ``` 33 | 34 | 35 | 36 | 37 | Also, please consider upgrading your app to [Chart.js v3](#upgrading-to-chartjs-v3). 38 | 39 | ## Upgrading to Chart.js v4 40 | 41 | First, upgrade packages. You'll need to install Chart.js v3 and the latest version of this library: 42 | 43 | 44 | 45 | 46 | ```bash 47 | yarn add chart.js@^4.0.0 react-chartjs-2@^5.0.0 48 | ``` 49 | 50 | 51 | 52 | 53 | ```bash 54 | pnpm add chart.js@^4.0.0 react-chartjs-2@^5.0.0 55 | ``` 56 | 57 | 58 | 59 | 60 | ```bash 61 | npm install --save chart.js@^4.0.0 react-chartjs-2@^5.0.0 62 | ``` 63 | 64 | 65 | 66 | 67 | Then, please follow the [this guide](/docs/migration-to-v5). 68 | -------------------------------------------------------------------------------- /website/docs/components/bar.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Description of Bar component from react-chartjs-2. 3 | --- 4 | 5 | import PropsTable from '../../src/components/PropsTable' 6 | 7 | # Bar 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import { Bar } from 'react-chartjs-2'; 13 | 14 | 19 | ``` 20 | 21 | [See full usage examples.](/tags/bar-chart) 22 | 23 | ## Props 24 | 25 | Also supports all standard `` props. 26 | 27 | 28 | -------------------------------------------------------------------------------- /website/docs/components/bubble.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Description of Bubble component from react-chartjs-2. 3 | --- 4 | 5 | import PropsTable from '../../src/components/PropsTable' 6 | 7 | # Bubble 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import { Bubble } from 'react-chartjs-2'; 13 | 14 | 19 | ``` 20 | 21 | [See full usage examples.](/tags/bubble-chart) 22 | 23 | ## Props 24 | 25 | Also supports all standard `` props. 26 | 27 | 28 | -------------------------------------------------------------------------------- /website/docs/components/chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Description of Chart component from react-chartjs-2. 3 | --- 4 | 5 | import PropsTable from '../../src/components/PropsTable' 6 | 7 | # Chart 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import { Chart } from 'react-chartjs-2'; 13 | 14 | 20 | ``` 21 | 22 | [See full usage examples.](/tags/chart) 23 | 24 | ## Props 25 | 26 | Also supports all standard `` props. 27 | 28 | 29 | -------------------------------------------------------------------------------- /website/docs/components/docs.js: -------------------------------------------------------------------------------- 1 | exports.docs = [ 2 | { title: 'Chart', slug: '/components/chart' }, 3 | { title: 'Bar', slug: '/components/bar' }, 4 | { title: 'Line', slug: '/components/line' }, 5 | { title: 'Pie', slug: '/components/pie' }, 6 | { title: 'Doughnut', slug: '/components/doughnut' }, 7 | { title: 'PolarArea', slug: '/components/polar-area' }, 8 | { title: 'Radar', slug: '/components/radar' }, 9 | { title: 'Scatter', slug: '/components/scatter' }, 10 | { title: 'Bubble', slug: '/components/bubble' }, 11 | ]; 12 | -------------------------------------------------------------------------------- /website/docs/components/doughnut.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Description of Doughnut component from react-chartjs-2. 3 | --- 4 | 5 | import PropsTable from '../../src/components/PropsTable' 6 | 7 | # Doughnut 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import { Doughnut } from 'react-chartjs-2'; 13 | 14 | 19 | ``` 20 | 21 | [See full usage examples.](/tags/doughnut-chart) 22 | 23 | ## Props 24 | 25 | Also supports all standard `` props. 26 | 27 | 28 | -------------------------------------------------------------------------------- /website/docs/components/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /components 3 | description: List of react-chartjs-2 components. 4 | --- 5 | 6 | import Link from '@docusaurus/Link'; 7 | import { docs } from './docs'; 8 | 9 | # Components 10 | 11 |
    12 | {docs.map(({ title, slug }, i) => ( 13 |
  • 14 | {title} 15 |
  • 16 | ))} 17 |
18 | -------------------------------------------------------------------------------- /website/docs/components/line.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Description of Line component from react-chartjs-2. 3 | --- 4 | 5 | import PropsTable from '../../src/components/PropsTable' 6 | 7 | # Line 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import { Line } from 'react-chartjs-2'; 13 | 14 | 19 | ``` 20 | 21 | [See full usage examples.](/tags/line-chart) 22 | 23 | ## Props 24 | 25 | Also supports all standard `` props. 26 | 27 | 28 | -------------------------------------------------------------------------------- /website/docs/components/pie.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Description of Pie component from react-chartjs-2. 3 | --- 4 | 5 | import PropsTable from '../../src/components/PropsTable' 6 | 7 | # Pie 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import { Pie } from 'react-chartjs-2'; 13 | 14 | 19 | ``` 20 | 21 | [See full usage examples.](/tags/pie-chart) 22 | 23 | ## Props 24 | 25 | Also supports all standard `` props. 26 | 27 | 28 | -------------------------------------------------------------------------------- /website/docs/components/polar-area.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Description of PolarArea component from react-chartjs-2. 3 | --- 4 | 5 | import PropsTable from '../../src/components/PropsTable' 6 | 7 | # PolarArea 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import { PolarArea } from 'react-chartjs-2'; 13 | 14 | 19 | ``` 20 | 21 | [See full usage examples.](/tags/polar-area-chart) 22 | 23 | ## Props 24 | 25 | Also supports all standard `` props. 26 | 27 | 28 | -------------------------------------------------------------------------------- /website/docs/components/radar.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Description of Radar component from react-chartjs-2. 3 | --- 4 | 5 | import PropsTable from '../../src/components/PropsTable' 6 | 7 | # Radar 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import { Radar } from 'react-chartjs-2'; 13 | 14 | 19 | ``` 20 | 21 | [See full usage examples.](/tags/radar-chart) 22 | 23 | ## Props 24 | 25 | Also supports all standard `` props. 26 | 27 | 28 | -------------------------------------------------------------------------------- /website/docs/components/scatter.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Description of Scatter component from react-chartjs-2. 3 | --- 4 | 5 | import PropsTable from '../../src/components/PropsTable' 6 | 7 | # Scatter 8 | 9 | ## Usage 10 | 11 | ```jsx 12 | import { Scatter } from 'react-chartjs-2'; 13 | 14 | 19 | ``` 20 | 21 | [See full usage examples.](/tags/scatter-chart) 22 | 23 | ## Props 24 | 25 | Also supports all standard `` props. 26 | 27 | 28 | -------------------------------------------------------------------------------- /website/docs/docs.js: -------------------------------------------------------------------------------- 1 | exports.docs = [ 2 | { title: 'Migration to v5', slug: '/docs/migration-to-v5' }, 3 | { title: 'Migration to v4', slug: '/docs/migration-to-v4' }, 4 | { title: 'Working with datasets', slug: '/docs/working-with-datasets' }, 5 | { title: 'Working with events', slug: '/docs/working-with-events' }, 6 | { title: 'Using with Chart.js v3', slug: '/docs/chartjs-v3' }, 7 | { title: 'Using with Chart.js v2', slug: '/docs/chartjs-v2' }, 8 | ]; 9 | -------------------------------------------------------------------------------- /website/docs/examples/area-chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of area chart in react-chartjs-2. 3 | tags: 4 | - Area Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Area Chart 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/bubble-chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of bubble chart in react-chartjs-2. 3 | tags: 4 | - Bubble Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Bubble Chart 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/chart-events.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of events in react-chartjs-2. 3 | tags: 4 | - Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Chart Events 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/chart-ref.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of getting ref in react-chartjs-2. 3 | tags: 4 | - Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Get Chart Ref 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/docs.js: -------------------------------------------------------------------------------- 1 | exports.docs = [ 2 | { title: 'Vertical Bar Chart', slug: '/examples/vertical-bar-chart' }, 3 | { title: 'Horizontal Bar Chart', slug: '/examples/horizontal-bar-chart' }, 4 | { title: 'Stacked Bar Chart', slug: '/examples/stacked-bar-chart' }, 5 | { title: 'Grouped Bar Chart', slug: '/examples/grouped-bar-chart' }, 6 | { title: 'Area Chart', slug: '/examples/area-chart' }, 7 | { title: 'Line Chart', slug: '/examples/line-chart' }, 8 | { title: 'Multiaxis Line Chart', slug: '/examples/multiaxis-line-chart' }, 9 | { title: 'Pie Chart', slug: '/examples/pie-chart' }, 10 | { title: 'Doughnut Chart', slug: '/examples/doughnut-chart' }, 11 | { title: 'Polar Area Chart', slug: '/examples/polar-area-chart' }, 12 | { title: 'Radar Chart', slug: '/examples/radar-chart' }, 13 | { title: 'Scatter Chart', slug: '/examples/scatter-chart' }, 14 | { title: 'Bubble Chart', slug: '/examples/bubble-chart' }, 15 | { title: 'Multitype Chart', slug: '/examples/multitype-chart' }, 16 | { title: 'Chart Events', slug: '/examples/chart-events' }, 17 | { title: 'Chart Ref', slug: '/examples/chart-ref' }, 18 | { title: 'Gradient Chart', slug: '/examples/gradient-chart' }, 19 | ]; 20 | -------------------------------------------------------------------------------- /website/docs/examples/doughnut-chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of doughnut chart in react-chartjs-2. 3 | tags: 4 | - Doughnut Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Doughnut Chart 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/gradient-chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of creating gradient chart in react-chartjs-2. 3 | tags: 4 | - Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Gradient Chart 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/grouped-bar-chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of grouped bar chart in react-chartjs-2. 3 | tags: 4 | - Bar Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Grouped Bar Chart 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/horizontal-bar-chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of horizontal bar chart in react-chartjs-2. 3 | tags: 4 | - Bar Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Horizontal Bar Chart 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /examples 3 | description: List of react-chartjs-2 usage examples. 4 | --- 5 | 6 | import Link from '@docusaurus/Link'; 7 | import { docs } from './docs'; 8 | 9 | # Examples 10 | 11 |
    12 | {docs.map(({ title, slug }, i) => ( 13 |
  • 14 | {title} 15 |
  • 16 | ))} 17 |
18 | -------------------------------------------------------------------------------- /website/docs/examples/line-chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of line chart in react-chartjs-2. 3 | tags: 4 | - Line Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Line Chart 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/multiaxis-line-chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of multiaxis line chart in react-chartjs-2. 3 | tags: 4 | - Line Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Multiaxis Line Chart 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/multitype-chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of multitype chart in react-chartjs-2. 3 | tags: 4 | - Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Multitype Chart 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/pie-chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of pie chart in react-chartjs-2. 3 | tags: 4 | - Pie Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Pie Chart 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/polar-area-chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of polar area chart in react-chartjs-2. 3 | tags: 4 | - Polar Area Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Polar Area Chart 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/radar-chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of radar chart in react-chartjs-2. 3 | tags: 4 | - Radar Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Radar Chart 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/scatter-chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of scatter chart in react-chartjs-2. 3 | tags: 4 | - Scatter Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Scatter Chart 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/stacked-bar-chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of stacked bar chart in react-chartjs-2. 3 | tags: 4 | - Bar Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Stacked Bar Chart 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/examples/vertical-bar-chart.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Example of vertical bar chart in react-chartjs-2. 3 | tags: 4 | - Bar Chart 5 | --- 6 | 7 | import ContextProvider from '../../src/components/ContextProvider'; 8 | 9 | # Vertical Bar Chart 10 | 11 | 12 | {({ branch, theme }) => ( 13 | 26 | )} 27 | 28 | -------------------------------------------------------------------------------- /website/docs/faq/canvas-context.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /faq/canvas-context 3 | --- 4 | 5 | # How to access the canvas context? 6 | 7 | The canvas node and hence context can be accessed by placing a ref to the element as: 8 | 9 | ```tsx 10 | function App() { 11 | const chartRef = useRef(null); 12 | 13 | useEffect(() => { 14 | const chart = chartRef.current; 15 | 16 | if (chart) { 17 | console.log('CanvasRenderingContext2D', chart.ctx); 18 | console.log('HTMLCanvasElement', chart.canvas); 19 | } 20 | }, []); 21 | 22 | return ; 23 | } 24 | ``` 25 | 26 | [See sandbox with working example](/examples/gradient-chart). 27 | -------------------------------------------------------------------------------- /website/docs/faq/chartjs-instance.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /faq/chartjs-instance 3 | --- 4 | 5 | # How to access the Chart.js instance? 6 | 7 | The Chart.js instance can be accessed by placing a ref to the element as: 8 | 9 | ```tsx 10 | function App() { 11 | const chartRef = useRef(null); 12 | 13 | useEffect(() => { 14 | const chart = chartRef.current; 15 | 16 | if (chart) { 17 | console.log('ChartJS', chart); 18 | } 19 | }, []); 20 | 21 | return ; 22 | } 23 | ``` 24 | 25 | [See sandbox with working example](/examples/chart-ref). 26 | 27 | -------------------------------------------------------------------------------- /website/docs/faq/docs.js: -------------------------------------------------------------------------------- 1 | exports.docs = [ 2 | { 3 | title: "Why doesn't the chart maintain its width/height?", 4 | slug: '/faq/maintain-aspect-ratio', 5 | }, 6 | { 7 | title: 'How to access the Chart.js instance?', 8 | slug: '/faq/chartjs-instance', 9 | }, 10 | { title: 'How to access the canvas context?', slug: '/faq/canvas-context' }, 11 | { 12 | title: 'Why this library has "2" in its name?', 13 | slug: '/faq/why-two', 14 | }, 15 | { 16 | title: 'Why is a background fill not working?', 17 | slug: '/faq/fill-property', 18 | }, 19 | { 20 | title: 'How to fix "... is not a registered element" error?', 21 | slug: '/faq/registered-element', 22 | }, 23 | { 24 | title: 'How to fix "... is not a registered scale" error?', 25 | slug: '/faq/registered-scale', 26 | }, 27 | { 28 | title: 'How to use react-chartjs-2 with TypeScript?', 29 | slug: '/faq/typescript', 30 | }, 31 | { 32 | title: 'How to fix "Cannot find module \'react-chartjs-2\'" error?', 33 | slug: '/faq/esm-only', 34 | }, 35 | ]; 36 | -------------------------------------------------------------------------------- /website/docs/faq/esm-only.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /faq/esm-only 3 | --- 4 | 5 | # How to fix "Cannot find module 'react-chartjs-2'" error? 6 | 7 | Upgrade to Chart.js v4.1 and react-chartjs-2 v5.1, where the CommonJS support was restored. 8 | -------------------------------------------------------------------------------- /website/docs/faq/fill-property.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /faq/fill-property 3 | --- 4 | 5 | # Why is a background fill not working? 6 | 7 | As you can see in [migration to v4 guide](/docs/migration-to-v4#tree-shaking): 8 | 9 | > v4 of this library, [just like Chart.js v3](https://www.chartjs.org/docs/latest/getting-started/v3-migration.html#setup-and-installation), is tree-shakable. It means that you need to import and register the controllers, elements, scales, and plugins you want to use. 10 | > 11 | > For a list of all the available items to import, see [Chart.js docs](https://www.chartjs.org/docs/latest/getting-started/integration.html#bundlers-webpack-rollup-etc). 12 | 13 | So to enable background filling, you should register `Filler` component: 14 | 15 | ```js 16 | import { Filler } from "chart.js"; 17 | 18 | ChartJS.register(Filler); 19 | ``` 20 | -------------------------------------------------------------------------------- /website/docs/faq/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /faq 3 | description: Frequently asked questions about react-chartjs-2. 4 | --- 5 | 6 | import Link from '@docusaurus/Link'; 7 | import { docs } from './docs'; 8 | 9 | # FAQ 10 | 11 |
    12 | {docs.map(({ title, slug }, i) => ( 13 |
  • 14 | {title} 15 |
  • 16 | ))} 17 |
18 | -------------------------------------------------------------------------------- /website/docs/faq/maintain-aspect-ratio.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /faq/maintain-aspect-ratio 3 | --- 4 | 5 | # Why doesn't the chart maintain its width/height? 6 | 7 | In order for Chart.js to obey the custom size you need to set `maintainAspectRatio` to `false`: 8 | 9 | ```tsx 10 | 16 | ``` 17 | -------------------------------------------------------------------------------- /website/docs/faq/registered-element.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /faq/registered-element 3 | --- 4 | 5 | # How to fix "... is not a registered element" error? 6 | 7 | As you can see in [migration to v4 guide](/docs/migration-to-v4#tree-shaking): 8 | 9 | > v4 of this library, [just like Chart.js v3](https://www.chartjs.org/docs/latest/getting-started/v3-migration.html#setup-and-installation), is tree-shakable. It means that you need to import and register the controllers, elements, scales, and plugins you want to use. 10 | > 11 | > For a list of all the available items to import, see [Chart.js docs](https://www.chartjs.org/docs/latest/getting-started/integration.html#bundlers-webpack-rollup-etc). 12 | 13 | So you should register missed components. For example, if you have `Uncaught Error: "arc" is not a registered element.` error, you should register `ArcElement`: 14 | 15 | ```js 16 | import { ArcElement } from "chart.js"; 17 | 18 | ChartJS.register(ArcElement); 19 | ``` 20 | -------------------------------------------------------------------------------- /website/docs/faq/registered-scale.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /faq/registered-scale 3 | --- 4 | 5 | # How to fix "... is not a registered scale" error? 6 | 7 | As you can see in [migration to v4 guide](/docs/migration-to-v4#tree-shaking): 8 | 9 | > v4 of this library, [just like Chart.js v3](https://www.chartjs.org/docs/latest/getting-started/v3-migration.html#setup-and-installation), is tree-shakable. It means that you need to import and register the controllers, elements, scales, and plugins you want to use. 10 | > 11 | > For a list of all the available items to import, see [Chart.js docs](https://www.chartjs.org/docs/latest/getting-started/integration.html#bundlers-webpack-rollup-etc). 12 | 13 | So you should register missed components. For example, if you have `Uncaught Error: "category" is not a registered scale.` error, you should register `CategoryScale`: 14 | 15 | ```js 16 | import { CategoryScale, Chart } from "chart.js"; 17 | 18 | Chart.register(CategoryScale); 19 | ``` 20 | -------------------------------------------------------------------------------- /website/docs/faq/typescript.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /faq/typescript 3 | --- 4 | 5 | # How to use react-chartjs-2 with TypeScript? 6 | 7 | TypeScript has extremely robust type inference capabilities and most of the time 8 | we can enjoy type safety and autocompletion without having to do any extra work. 9 | 10 | But occasionally types need to be set explicitly. They can be imported from `Chart.js`: 11 | 12 | ```typescript 13 | import type { ChartData, ChartOptions } from 'chart.js'; 14 | ``` 15 | 16 | ...and then used with `options` and `data` props: 17 | 18 | ```typescript 19 | interface LineProps { 20 | options: ChartOptions<'line'>; 21 | data: ChartData<'line'>; 22 | } 23 | ``` 24 | 25 | The generic type being passed is a `ChartType` that can be one of the following values: 26 | `'bar'`, `'line'`, `'scatter'`, `'bubble'`, `'pie'`, `'doughnut'`, `'polarArea'` or `'radar'`. 27 | -------------------------------------------------------------------------------- /website/docs/faq/why-two.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /faq/why-two 3 | --- 4 | 5 | # Why does `react-chartjs-2` have "2" in its name? 6 | 7 | Initially, this library was [created in 2016](https://github.com/reactchartjs/react-chartjs-2/commit/d8cbcb7dc050d749771c6bb1347e22ec63bdddf9#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R3) as a wrapper for Chart.js v2. 8 | 9 | Later, it was updated to support [Chart.js v3](https://www.chartjs.org/docs/latest/getting-started/v3-migration.html) — a huge yet backwards-incompatible release with new features and performance improvements. However, the name persisted. 10 | -------------------------------------------------------------------------------- /website/docs/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | slug: / 3 | description: React components for Chart.js 4 | --- 5 | 6 | import Tabs from '@theme/Tabs'; 7 | import TabItem from '@theme/TabItem'; 8 | import Logo from '@site/static/img/logo.svg'; 9 | 10 | # react-chartjs-2 11 | 12 | 13 | 14 | React components for [Chart.js](https://www.chartjs.org), the most popular charting library. 15 | 16 | Supports Chart.js v4 (read below) and Chart.js v3 (see [this guide](/docs/chartjs-v3)). 17 | 18 | [![NPM version][npm]][npm-url] 19 | [![Downloads][downloads]][downloads-url] 20 | [![Build status][build]][build-url] 21 | [![Coverage status][coverage]][coverage-url] 22 | [![Bundle size][size]][size-url] 23 | 24 | [npm]: https://img.shields.io/npm/v/react-chartjs-2.svg 25 | [npm-url]: https://www.npmjs.com/package/react-chartjs-2 26 | 27 | [downloads]: https://img.shields.io/npm/dm/react-chartjs-2.svg 28 | [downloads-url]: https://www.npmjs.com/package/react-chartjs-2 29 | 30 | [build]: https://img.shields.io/github/actions/workflow/status/reactchartjs/react-chartjs-2/ci.yml?branch=master 31 | [build-url]: https://github.com/reactchartjs/react-chartjs-2/actions 32 | 33 | [coverage]: https://img.shields.io/codecov/c/github/reactchartjs/react-chartjs-2.svg 34 | [coverage-url]: https://app.codecov.io/gh/reactchartjs/react-chartjs-2 35 | 36 | [size]: https://img.shields.io/bundlephobia/minzip/react-chartjs-2 37 | [size-url]: https://bundlephobia.com/package/react-chartjs-2 38 | 39 | ## Quickstart 40 | 41 | Install this library with peer dependencies: 42 | 43 | 44 | 45 | 46 | ```bash 47 | yarn add chart.js react-chartjs-2 48 | ``` 49 | 50 | 51 | 52 | 53 | ```bash 54 | pnpm add chart.js react-chartjs-2 55 | ``` 56 | 57 | 58 | 59 | 60 | ```bash 61 | npm install --save chart.js react-chartjs-2 62 | ``` 63 | 64 | 65 | 66 | 67 | Then, import and use individual components: 68 | 69 | ```jsx 70 | import { Chart as ChartJS, ArcElement, Tooltip, Legend } from "chart.js"; 71 | import { Doughnut } from "react-chartjs-2"; 72 | 73 | ChartJS.register(ArcElement, Tooltip, Legend); 74 | 75 | 76 | ``` 77 | 78 | To learn more about importing and registering elements see [tree-shaking](https://react-chartjs-2.js.org/docs/migration-to-v4/#tree-shaking). 79 | 80 | :::tip Need an API to fetch data? 81 | Please consider [Cube](https://cube.dev/?ref=eco-react-chartjs), an open-source API for data apps. 82 | ::: 83 | 84 | ## Examples 85 | 86 | Please see [live examples](/examples). 87 | 88 | :::tip Need a guide? 89 | Please check "[Chart.js Example with Dynamic Dataset](https://cube.dev/blog/chart-js-example-with-dynamic-dataset/?ref=eco-react-chartjs)". 90 | ::: 91 | 92 | ## Getting Help 93 | 94 | Need help? Ask your question on [Slack](https://slack.cube.dev/?ref=eco-react-chartjs) or [Stack Overflow](https://stackoverflow.com/questions/tagged/react-chartjs-2). 95 | 96 | If you've encountered an issue, please [file it on GitHub](https://github.com/reactchartjs/react-chartjs-2/issues). 97 | -------------------------------------------------------------------------------- /website/docs/migration-to-v4.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /docs/migration-to-v4 3 | description: react-chartjs-2 migration guide to v4 4 | --- 5 | 6 | # Migration to v4 7 | 8 | With v4, this library introduces a number of breaking changes. In order to improve performance, offer new features, and improve maintainability, it was necessary to break backwards compatibility, but we aimed to do so only when worth the benefit. 9 | 10 | v4 is fully compatible with Chart.js v3. 11 | 12 | ## New exports 13 | 14 | - All re-exports from `chart.js` were removed 15 | - Default export was renamed to `Chart` 16 | 17 | ```jsx title="v3" 18 | import Chart, { 19 | Chart as ChartJS, 20 | defaults 21 | } from 'react-chartjs-2'; 22 | ``` 23 | 24 | ```jsx title="v4" 25 | import { 26 | Chart as ChartJS, 27 | defaults 28 | } from 'chart.js'; 29 | import { 30 | Chart 31 | } from 'react-chartjs-2'; 32 | ``` 33 | 34 | ## Tree-shaking 35 | 36 | v4 of this library, [just like Chart.js v3](https://www.chartjs.org/docs/latest/getting-started/v3-migration.html#setup-and-installation), is tree-shakable. It means that you need to import and register the controllers, elements, scales, and plugins you want to use. 37 | 38 | For a list of all the available items to import, see [Chart.js docs](https://www.chartjs.org/docs/latest/getting-started/integration.html#bundlers-webpack-rollup-etc). 39 | 40 | ```jsx title="v3" 41 | import Chart from 'react-chartjs-2'; 42 | 43 | 44 | ``` 45 | 46 | ```jsx title="v4 — lazy way" 47 | import 'chart.js/auto'; 48 | import { Chart } from 'react-chartjs-2'; 49 | 50 | 51 | ``` 52 | 53 | ```jsx title="v4 — tree-shakable way" 54 | import { Chart } from 'react-chartjs-2'; 55 | import { Chart as ChartJS, LineController, LineElement, PointElement, LinearScale, Title } from 'chart.js'; 56 | 57 | ChartJS.register(LineController, LineElement, PointElement, LinearScale, Title); 58 | 59 | 60 | ``` 61 | 62 | Using the "lazy way" is okay to simplify the migration, but please consider using the tree-shakable way to decrease the bundle size. 63 | 64 | Please note that typed chart components register their controllers by default, so you don't need to register them by yourself. For example, when using the [`Line` component](/components/line), you don't need to register `LineController` explicitly. 65 | 66 | ```jsx title="v4 — Line component" 67 | import { Line } from 'react-chartjs-2'; 68 | import { Chart as ChartJS, LineElement, PointElement, LinearScale, Title } from 'chart.js'; 69 | 70 | ChartJS.register(LineElement, PointElement, LinearScale, Title); 71 | 72 | 73 | ``` 74 | 75 | ## Drawing charts with gradients 76 | 77 | The option to pass a function to the `data` prop was removed. 78 | 79 | ```jsx title="v3" 80 | const chartData = canvas => { 81 | const ctx = canvas.getContext('2d'); 82 | 83 | return { 84 | datasets: [{ 85 | backgroundColor: createBackgroundGradient(ctx), 86 | // ... 87 | }], 88 | }; 89 | }; 90 | 91 | 92 | ``` 93 | 94 | ```jsx title="v4" 95 | const chartRef = useRef(null); 96 | const [chartData, setChartData] = useState({ 97 | datasets: [], 98 | }); 99 | 100 | useEffect(() => { 101 | const chart = chartRef.current; 102 | 103 | if (chart) { 104 | setChartData({ 105 | datasets: [{ 106 | backgroundColor: createBackgroundGradient(chart.ctx), 107 | // ... 108 | }] 109 | }); 110 | } 111 | }, []); 112 | 113 | 114 | ``` 115 | 116 | See the [full working example](/examples/gradient-chart). 117 | 118 | ## Getting data from click events 119 | 120 | `getDatasetAtEvent`, `getElementAtEvent` and `getElementsAtEvent` props were removed in favor of tree-shakable methods with the same names. 121 | 122 | ```jsx title="v3" 123 | { /* ... */ }} 127 | getElementAtEvent={(element, event) => { /* ... */ }} 128 | getElementsAtEvent={(elements, event) => { /* ... */ }} 129 | /> 130 | ``` 131 | 132 | ```jsx title="v4" 133 | const chartRef = useRef(null); 134 | 135 | { 140 | const dataset = getDatasetAtEvent(chartRef.current, event); 141 | const element = getElementAtEvent(chartRef.current, event); 142 | const elements = getElementsAtEvent(chartRef.current, event); 143 | }} 144 | /> 145 | ``` 146 | 147 | See the [full working example](/examples/chart-events). 148 | -------------------------------------------------------------------------------- /website/docs/migration-to-v5.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /docs/migration-to-v5 3 | description: react-chartjs-2 migration guide to v5 4 | --- 5 | 6 | # Migration to v5 7 | 8 | ## v5.0 9 | 10 | Chart.js v4 and react-chartjs-2 v5 are [ESM-only packages](https://nodejs.org/api/esm.html). To use them in your project, it also should be ESM: 11 | 12 | ```json title="package.json" 13 | { 14 | "type": "module" 15 | } 16 | ``` 17 | 18 | ## v5.1 19 | 20 | Chart.js v4.1 and react-chartjs-2 v5.1 have restored the CommonJS support. 21 | -------------------------------------------------------------------------------- /website/docs/working-with-datasets.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /docs/working-with-datasets 3 | description: Working with datasets in react-chartjs-2 4 | --- 5 | 6 | # Working with datasets 7 | 8 | You will find that any event which causes the chart to re-render, such as hover tooltips, etc., will cause the first dataset to be copied over to other datasets, causing your lines and bars to merge together. 9 | 10 | This is because to track changes in the dataset series, the library needs a `key` to be specified. If none is found, it can't tell the difference between the datasets while updating. To get around this issue, you can take these two approaches: 11 | 12 | 1. Add a `label` property to each dataset. By default, this library uses the `label` property as the key to distinguish datasets. 13 | 2. Specify a different property to be used as a key by passing a `datasetIdKey` prop to your chart component. 14 | 15 | See this example: 16 | 17 | ```tsx 18 | import { Line } from 'react-chartjs-2'; 19 | 20 | 38 | ``` 39 | -------------------------------------------------------------------------------- /website/docs/working-with-events.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /docs/working-with-events 3 | description: Working with events in react-chartjs-2 4 | --- 5 | 6 | # Working with events 7 | 8 | There are three helper methods to get data from click event. 9 | 10 | ## getDatasetAtEvent 11 | 12 | Gets dataset from mouse click event. 13 | 14 | ```jsx 15 | import { useRef } from 'react'; 16 | import { Bar, getDatasetAtEvent } from 'react-chartjs-2'; 17 | 18 | function App() { 19 | const chartRef = useRef(); 20 | const onClick = (event) => { 21 | console.log(getDatasetAtEvent(chartRef.current, event)); 22 | } 23 | 24 | return ( 25 | 30 | ); 31 | } 32 | ``` 33 | 34 | ## getElementAtEvent 35 | 36 | Gets single dataset element from mouse click event. 37 | 38 | ```jsx 39 | import { useRef } from 'react'; 40 | import { Bar, getElementAtEvent } from 'react-chartjs-2'; 41 | 42 | function App() { 43 | const chartRef = useRef(); 44 | const onClick = (event) => { 45 | console.log(getElementAtEvent(chartRef.current, event)); 46 | } 47 | 48 | return ( 49 | 54 | ); 55 | } 56 | ``` 57 | 58 | ## getElementsAtEvent 59 | 60 | Gets all dataset elements from mouse click event. 61 | 62 | ```jsx 63 | import { useRef } from 'react'; 64 | import { Bar, getElementsAtEvent } from 'react-chartjs-2'; 65 | 66 | function App() { 67 | const chartRef = useRef(); 68 | const onClick = (event) => { 69 | console.log(getElementsAtEvent(chartRef.current, event)); 70 | } 71 | 72 | return ( 73 | 78 | ); 79 | } 80 | ``` 81 | 82 | See the [full working example](/examples/chart-events). 83 | -------------------------------------------------------------------------------- /website/docusaurus.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | const branch = require('git-branch'); 4 | const lightCodeTheme = require('prism-react-renderer/themes/github'); 5 | const darkCodeTheme = require('prism-react-renderer/themes/dracula'); 6 | 7 | const currentBranch = process.env.BRANCH || branch.sync(); 8 | 9 | /** @type {import('@docusaurus/types').Config} */ 10 | const config = { 11 | title: 'react-chartjs-2', 12 | tagline: 'React wrapper for Chart.js', 13 | url: 'https://react-chartjs-2.js.org', 14 | baseUrl: '/', 15 | onBrokenLinks: 'throw', 16 | onBrokenMarkdownLinks: 'warn', 17 | favicon: 'img/favicon.ico', 18 | organizationName: 'reactchartjs', 19 | projectName: 'react-chartjs-2', 20 | noIndex: currentBranch !== 'master', 21 | 22 | customFields: { 23 | branch: currentBranch, 24 | }, 25 | 26 | presets: [ 27 | [ 28 | '@docusaurus/preset-classic', 29 | /** @type {import('@docusaurus/preset-classic').Options} */ 30 | ({ 31 | docs: { 32 | routeBasePath: '/', 33 | sidebarPath: require.resolve('./sidebars.js'), 34 | editUrl: 35 | 'https://github.com/reactchartjs/react-chartjs-2/edit/master/website/', 36 | }, 37 | theme: { 38 | customCss: require.resolve('./src/css/custom.css'), 39 | }, 40 | }), 41 | ], 42 | ], 43 | 44 | themeConfig: 45 | /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ 46 | ({ 47 | navbar: { 48 | title: 'react-chartjs-2', 49 | logo: { 50 | alt: 'react-chartjs-2 logo', 51 | src: 'img/logo.svg', 52 | }, 53 | items: [ 54 | { 55 | type: 'doc', 56 | docId: 'faq/index', 57 | position: 'left', 58 | label: 'FAQ', 59 | }, 60 | { 61 | type: 'doc', 62 | docId: 'components/index', 63 | position: 'left', 64 | label: 'Components', 65 | }, 66 | { 67 | type: 'doc', 68 | docId: 'examples/index', 69 | position: 'left', 70 | label: 'Examples', 71 | }, 72 | { 73 | href: 'https://slack.cube.dev/?ref=eco-react-chartjs', 74 | label: 'Slack', 75 | position: 'right', 76 | }, 77 | { 78 | href: 'https://stackoverflow.com/questions/tagged/react-chartjs-2', 79 | label: 'Stack Overflow', 80 | position: 'right', 81 | }, 82 | { 83 | href: 'https://github.com/reactchartjs/react-chartjs-2', 84 | label: 'GitHub', 85 | position: 'right', 86 | }, 87 | ], 88 | }, 89 | prism: { 90 | theme: lightCodeTheme, 91 | darkTheme: darkCodeTheme, 92 | }, 93 | algolia: { 94 | appId: 'BH4D9OD16A', 95 | apiKey: 'd59187de89e7935f588bbb2fc9273f03', 96 | indexName: 'react-chartjs-2', 97 | }, 98 | }), 99 | 100 | plugins: [ 101 | [ 102 | 'docusaurus-plugin-react-docgen-typescript', 103 | { 104 | src: '../src/**/*.tsx', 105 | parserOptions: { 106 | propFilter: prop => { 107 | if (prop.parent) { 108 | return !prop.parent.fileName.includes('@types/react'); 109 | } 110 | 111 | return true; 112 | }, 113 | }, 114 | }, 115 | ], 116 | ], 117 | }; 118 | 119 | module.exports = config; 120 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids", 15 | "typecheck": "tsc" 16 | }, 17 | "dependencies": { 18 | "@algolia/client-search": "^4.11.0", 19 | "@docusaurus/core": "2.0.0-beta.14", 20 | "@docusaurus/preset-classic": "2.0.0-beta.14", 21 | "@docusaurus/theme-search-algolia": "^2.0.0-beta.9", 22 | "@mdx-js/react": "^1.6.21", 23 | "@svgr/webpack": "^6.0.0", 24 | "clsx": "^1.1.1", 25 | "docusaurus-plugin-react-docgen-typescript": "^0.1.0", 26 | "file-loader": "^6.2.0", 27 | "git-branch": "^2.0.1", 28 | "prism-react-renderer": "^1.2.1", 29 | "react": "^18.0.0", 30 | "react-docgen-typescript": "^2.1.1", 31 | "react-dom": "^18.0.0", 32 | "url-loader": "^4.1.1" 33 | }, 34 | "devDependencies": { 35 | "@docusaurus/module-type-aliases": "2.0.0-beta.14", 36 | "@tsconfig/docusaurus": "^1.0.4", 37 | "@types/react": "^18.0.0", 38 | "typescript": "^4.3.5", 39 | "webpack": "^5.64.2" 40 | }, 41 | "browserslist": { 42 | "production": [ 43 | ">0.5%", 44 | "not dead", 45 | "not op_mini all" 46 | ], 47 | "development": [ 48 | "last 1 chrome version", 49 | "last 1 firefox version", 50 | "last 1 safari version" 51 | ] 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /website/sidebars.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | const { docs } = require('./docs/docs'); 4 | const { docs: faq } = require('./docs/faq/docs'); 5 | const { docs: components } = require('./docs/components/docs'); 6 | const { docs: examples } = require('./docs/examples/docs'); 7 | 8 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 9 | const sidebars = { 10 | docsSidebar: [ 11 | { 12 | type: 'doc', 13 | id: 'index', 14 | label: 'Quickstart', 15 | }, 16 | ...docs.map(({ slug, title }) => ({ 17 | /** @type {'doc'} */ 18 | type: 'doc', 19 | id: slug.replace('/docs/', ''), 20 | label: title, 21 | })), 22 | ], 23 | faqSidebar: [ 24 | { 25 | type: 'doc', 26 | id: 'faq/index', 27 | label: 'Table of Contents', 28 | }, 29 | ...faq.map(({ slug, title }) => ({ 30 | /** @type {'doc'} */ 31 | type: 'doc', 32 | id: slug.replace('/', ''), 33 | label: title, 34 | })), 35 | ], 36 | componentsSidebar: [ 37 | { 38 | type: 'doc', 39 | id: 'components/index', 40 | label: 'Table of Contents', 41 | }, 42 | ...components.map(({ slug, title }) => ({ 43 | /** @type {'doc'} */ 44 | type: 'doc', 45 | id: slug.replace('/', ''), 46 | label: title, 47 | })), 48 | ], 49 | examplesSidebar: [ 50 | { 51 | type: 'doc', 52 | id: 'examples/index', 53 | label: 'Table of Contents', 54 | }, 55 | ...examples.map(({ slug, title }) => ({ 56 | /** @type {'doc'} */ 57 | type: 'doc', 58 | id: slug.replace('/', ''), 59 | label: title, 60 | })), 61 | ], 62 | }; 63 | 64 | module.exports = sidebars; 65 | -------------------------------------------------------------------------------- /website/src/components/ContextProvider.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from 'react'; 2 | import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; 3 | import useThemeContext from '@theme/hooks/useThemeContext'; 4 | 5 | interface IContext { 6 | branch: string; 7 | theme: 'light' | 'dark'; 8 | } 9 | 10 | export default function ContextProvider({ 11 | children, 12 | }: { 13 | children(context: IContext): ReactNode; 14 | }) { 15 | const ctx = useDocusaurusContext(); 16 | const { isDarkTheme } = useThemeContext(); 17 | const context = { 18 | branch: ctx.siteConfig.customFields.branch as string, 19 | theme: isDarkTheme ? ('dark' as const) : ('light' as const), 20 | }; 21 | 22 | return children(context); 23 | } 24 | -------------------------------------------------------------------------------- /website/src/components/PropsTable.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Link from '@docusaurus/Link'; 3 | import { useDynamicImport } from 'docusaurus-plugin-react-docgen-typescript/pkg/dist-src/hooks/useDynamicImport'; 4 | 5 | function clean(description: string) { 6 | return description.replace(/\n@.*/g, ''); 7 | } 8 | 9 | function see(description: string) { 10 | const results = description.match(/@see (.*)/); 11 | 12 | if (!results) { 13 | return null; 14 | } 15 | 16 | const [, link] = results; 17 | 18 | return ( 19 | <> 20 |
21 | See more 22 | 23 | ); 24 | } 25 | 26 | export default function PropsTable({ component }: { component: string }) { 27 | const props = useDynamicImport(component); 28 | 29 | if (!props) { 30 | return null; 31 | } 32 | 33 | return ( 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | {Object.keys(props).map(key => { 46 | return ( 47 | 48 | 51 | 54 | 59 | 60 | 64 | 65 | ); 66 | })} 67 | 68 |
NameTypeDefault ValueRequiredDescription
49 | {key} 50 | 52 | {props[key].type?.name} 53 | 55 | {props[key].defaultValue && ( 56 | {props[key].defaultValue.value} 57 | )} 58 | {props[key].required ? 'Yes' : 'No'} 61 | {clean(props[key].description)} 62 | {see(props[key].description)} 63 |
69 | ); 70 | } 71 | -------------------------------------------------------------------------------- /website/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Any CSS included here will be global. The classic template 3 | * bundles Infima by default. Infima is a CSS framework designed to 4 | * work well for content-centric websites. 5 | */ 6 | 7 | /* You can override the default Infima variables here. */ 8 | :root { 9 | --ifm-color-primary: #7a77ff; 10 | --ifm-color-primary-dark: #5552ff; 11 | --ifm-color-primary-darker: #433fff; 12 | --ifm-color-primary-darkest: #0c07ff; 13 | --ifm-color-primary-light: #9f9cff; 14 | --ifm-color-primary-lighter: #b1afff; 15 | --ifm-color-primary-lightest: #e8e7ff; 16 | --ifm-code-font-size: 95%; 17 | } 18 | 19 | .docusaurus-highlight-code-line { 20 | background-color: rgba(0, 0, 0, 0.1); 21 | display: block; 22 | margin: 0 calc(-1 * var(--ifm-pre-padding)); 23 | padding: 0 var(--ifm-pre-padding); 24 | } 25 | 26 | html[data-theme='dark'] .docusaurus-highlight-code-line { 27 | background-color: rgba(0, 0, 0, 0.3); 28 | } 29 | 30 | .logo { 31 | float: right; 32 | } 33 | 34 | @media (max-width: 768px) { 35 | .logo { 36 | float: none; 37 | display: block; 38 | margin: 0 auto; 39 | } 40 | } 41 | 42 | @media (min-width: 3160px) { 43 | .container { 44 | max-width: 2440px; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /website/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ronaldtech051/React-ChartJS/39e3f6fd0dff7c20eb1aebd89a15028a0625a75a/website/static/.nojekyll -------------------------------------------------------------------------------- /website/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ronaldtech051/React-ChartJS/39e3f6fd0dff7c20eb1aebd89a15028a0625a75a/website/static/img/favicon.ico -------------------------------------------------------------------------------- /website/static/img/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 12 | 13 | 14 | 17 | 18 | 19 | 22 | 25 | 28 | 31 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /website/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // This file is not used in compilation. It is here just for a nice editor experience. 3 | "extends": "@tsconfig/docusaurus/tsconfig.json", 4 | "compilerOptions": { 5 | "baseUrl": "." 6 | } 7 | } 8 | --------------------------------------------------------------------------------