diff --git a/README.md b/README.md index 162b9b5..d34e21c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -![](https://img.shields.io/endpoint?url=https://codecentral.devexpress.com/api/v1/VersionRange/1015331587/25.1.3%2B) [![](https://img.shields.io/badge/Open_in_DevExpress_Support_Center-FF7200?style=flat-square&logo=DevExpress&logoColor=white)](https://supportcenter.devexpress.com/ticket/details/T1298736) [![](https://img.shields.io/badge/📖_How_to_use_DevExpress_Examples-e9f6fc?style=flat-square)](https://docs.devexpress.com/GeneralInformation/403183) [![](https://img.shields.io/badge/💬_Leave_Feedback-feecdd?style=flat-square)](#does-this-example-address-your-development-requirementsobjectives) diff --git a/React/package-lock.json b/React/package-lock.json index c2b4f96..124ff18 100644 --- a/React/package-lock.json +++ b/React/package-lock.json @@ -8,8 +8,8 @@ "name": "react", "version": "0.0.0", "dependencies": { - "devextreme": "^24.2.3", - "devextreme-react": "^24.2.3", + "devextreme": "^25.1.3", + "devextreme-react": "^25.1.3", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -36,7 +36,7 @@ "ts-node": "10.9.2", "typescript": "~5.8.2", "typescript-eslint": "^8.18.2", - "vite": "^6.3.5", + "vite": "^7.0.0", "vitest": "^1.5.0" } }, @@ -681,17 +681,6 @@ "tslib": "2.3.1" } }, - "node_modules/@devextreme/runtime": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@devextreme/runtime/-/runtime-3.0.13.tgz", - "integrity": "sha512-//24I6vo5a+XG/Ul3+vOGqU4M22IWyldpECxLY8iyGJWA5fiNaYzAedrMV2Ixo5oRj8DawiHTZKy5iKKF9ks5g==", - "license": "SEE LICENSE IN LICENSE", - "dependencies": { - "inferno": "^7.4.6", - "inferno-create-element": "^7.4.6", - "inferno-hydrate": "^7.4.6" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", @@ -1392,6 +1381,16 @@ "node": ">= 8" } }, + "node_modules/@preact/signals-core": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.11.0.tgz", + "integrity": "sha512-jglbibeWHuFRzEWVFY/TT7wB1PppJxmcSfUHcK+2J9vBRtiooMfw6tAPttojNYrrpdGViqAYCbPpmWYlMm+eMQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.9", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.9.tgz", @@ -3274,9 +3273,9 @@ "license": "MIT" }, "node_modules/core-js": { - "version": "3.42.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.42.0.tgz", - "integrity": "sha512-Sz4PP4ZA+Rq4II21qkNqOEDTDrCvcANId3xpIgB34NDkWc3UduWj2dqEtN9yZIq8Dk3HyPI33x9sqqU5C8sr0g==", + "version": "3.43.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.43.0.tgz", + "integrity": "sha512-N6wEbTTZSYOY2rYAn85CuvWWkCK6QweMn7/4Nr3w+gDBeBhk/x4EJeY6FPo4QzDoJZxVTv8U7CMvgWk6pOHHqA==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -3427,7 +3426,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true, "license": "MIT" }, "node_modules/damerau-levenshtein": { @@ -3698,9 +3696,9 @@ } }, "node_modules/devexpress-diagram": { - "version": "2.2.16", - "resolved": "https://registry.npmjs.org/devexpress-diagram/-/devexpress-diagram-2.2.16.tgz", - "integrity": "sha512-O60EjxtHKzedhl9M9bv3yLHBDylpAMQEtTJ2HcmuJyYTKA5SRccpf/BvtKzl43C0tSjPN2jJAYYGruZoIqOVOg==", + "version": "2.2.18", + "resolved": "https://registry.npmjs.org/devexpress-diagram/-/devexpress-diagram-2.2.18.tgz", + "integrity": "sha512-zHWkrBbGDBbMBgK4fFsNlaMzcngf1DrTvbs0IHNHfBSsIDrNy8t3BXRgrLXWgFr8UCsYpkYx2aHGZ6kvsN/kWg==", "license": "SEE LICENSE IN README.md", "dependencies": { "@devexpress/utils": "^1.4.3", @@ -3708,9 +3706,9 @@ } }, "node_modules/devexpress-gantt": { - "version": "4.1.60", - "resolved": "https://registry.npmjs.org/devexpress-gantt/-/devexpress-gantt-4.1.60.tgz", - "integrity": "sha512-EreGiSrxOk9kSkBsslPr3oFCxxhRRev6dmzgR/7dEzNxgZPE0KRnW8hYwZqu8tmx9o5m5Z59nv7CQ5kEczNlrA==", + "version": "4.1.62", + "resolved": "https://registry.npmjs.org/devexpress-gantt/-/devexpress-gantt-4.1.62.tgz", + "integrity": "sha512-8ULKoAyStlFnATNkkYFZWB7eQHrxJPallq04+HHiu9fn1TIRz0SgYlQdZuXoOmEhcRhaNwk5d+38sJ6OMC0HnQ==", "license": "SEE LICENSE IN README.md", "dependencies": { "@devexpress/utils": "^1.4.3", @@ -3718,19 +3716,19 @@ } }, "node_modules/devextreme": { - "version": "24.2.7", - "resolved": "https://registry.npmjs.org/devextreme/-/devextreme-24.2.7.tgz", - "integrity": "sha512-f32EtlOcsOYoG7j5XoYgH3a9pcguwvbG0RWPNx4iHp1g0nlvwH1JVplzN0++b5lLR/IHu73JgoRsjoFnj349Kg==", + "version": "25.1.3", + "resolved": "https://registry.npmjs.org/devextreme/-/devextreme-25.1.3.tgz", + "integrity": "sha512-72J3vL+QbQWEfUTzNuPTEsyN/+Nnb4jI/BwymcUHcBUKKp4vf3m72KviteHxutobblcfzvZmxLQCEvn01T/EqA==", "license": "SEE LICENSE IN README.md", "dependencies": { "@babel/runtime": "^7.12.1", - "@devextreme/runtime": "3.0.13", - "devexpress-diagram": "2.2.16", - "devexpress-gantt": "4.1.60", - "devextreme-quill": "1.7.2", - "inferno": "^7.4.9", - "inferno-create-element": "^7.4.9", - "inferno-hydrate": "^7.4.9", + "@preact/signals-core": "^1.8.0", + "devexpress-diagram": "2.2.18", + "devexpress-gantt": "4.1.62", + "devextreme-quill": "1.7.3", + "inferno": "^8.2.3", + "inferno-create-element": "^8.2.3", + "inferno-hydrate": "^8.2.3", "jszip": "^3.10.1", "rrule": "^2.7.1" }, @@ -3740,30 +3738,29 @@ } }, "node_modules/devextreme-quill": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/devextreme-quill/-/devextreme-quill-1.7.2.tgz", - "integrity": "sha512-Ng+3ULPwGhLnCqstLRqnDF8Jj2P40sgjTjWzwgCYzH9G9E1n5IvzRl6weFzDWeytRM1WfsxX8Xdr2Oumf/2CDA==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/devextreme-quill/-/devextreme-quill-1.7.3.tgz", + "integrity": "sha512-YPE9e8UOOByf/QUBAGZRmCDHFzQDnM+hyPet6vFNFGm2UsJAIz4xkL6gDhfan/a6otInQUB5wLsbPZqldZrliQ==", "license": "BSD-3-Clause", "dependencies": { "core-js": "^3.34.0", "eventemitter3": "^4.0.7", "lodash.clonedeep": "^4.5.0", - "lodash.isequal": "^4.5.0", "lodash.merge": "^4.6.2", "parchment": "^2.0.1", "quill-delta": "^5.0.0" } }, "node_modules/devextreme-react": { - "version": "24.2.7", - "resolved": "https://registry.npmjs.org/devextreme-react/-/devextreme-react-24.2.7.tgz", - "integrity": "sha512-VVY3Y7vjHC99rI/uZNTFGvh3gd5H3HhWd2rX64dRvt6KCy0Oh2PCLdvsmox+NaMpk2mQcv3KjgtbrFAk31DhDg==", + "version": "25.1.3", + "resolved": "https://registry.npmjs.org/devextreme-react/-/devextreme-react-25.1.3.tgz", + "integrity": "sha512-reTLUl9tC1KFb5bjY60G6Cyy8svXHTrTYeiYtx/kiaZq+NjyQ0ez67dALWyzKAVbzTWqoUWO/E/z9iwzNjcsUA==", "license": "MIT", "dependencies": { "prop-types": "^15.8.1" }, "peerDependencies": { - "devextreme": "~24.2.7", + "devextreme": "25.1.3", "react": "^16.2.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.2.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } @@ -5617,45 +5614,43 @@ } }, "node_modules/inferno": { - "version": "7.4.11", - "resolved": "https://registry.npmjs.org/inferno/-/inferno-7.4.11.tgz", - "integrity": "sha512-N+cs33ESWI8fdToCd98yMRYl7jkLnCkJskxov3FKKlaKOvk3PRlAttbhmUaYdWXlRvt2WeXi+J4MbzNj3V6G0w==", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/inferno/-/inferno-8.2.3.tgz", + "integrity": "sha512-LMeRlCe+RlXw8kHCLyOWRk2PsZ3Fo4jkESyAR1g4FfPT48N78i11YhTVXW2ukCx5MFjv+qrfa73JzJWU9sg4CQ==", "hasInstallScript": true, "license": "MIT", "dependencies": { - "inferno-shared": "7.4.11", - "inferno-vnode-flags": "7.4.11", + "csstype": "^3.1.2", + "inferno-vnode-flags": "8.2.3", "opencollective-postinstall": "^2.0.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/inferno" } }, "node_modules/inferno-create-element": { - "version": "7.4.11", - "resolved": "https://registry.npmjs.org/inferno-create-element/-/inferno-create-element-7.4.11.tgz", - "integrity": "sha512-kE6XIx2hPAd5qpDli2iGjNXgubvuyxdLvoiW71WnSzIIxA+Uxa/s8lY8m03VyHHVypFV3n329ZY5dFvKc7UQMg==", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/inferno-create-element/-/inferno-create-element-8.2.3.tgz", + "integrity": "sha512-YEwX4OiFlgeTutvE16uCGxkaSVwZ1DklpAPX8okjVsGaLIWQrM8QIQFxn3mTLWSu70Uea+afQfKL5wE4hxn39Q==", "license": "MIT", "dependencies": { - "inferno": "7.4.11" + "inferno": "8.2.3" } }, "node_modules/inferno-hydrate": { - "version": "7.4.11", - "resolved": "https://registry.npmjs.org/inferno-hydrate/-/inferno-hydrate-7.4.11.tgz", - "integrity": "sha512-hF9Ke4GHAkj8GQrMXBZPfsUqhq6WjkoDCAfXhPBuF1Wiceqyy8KerOOXEnuocHky77fuEXq0AzVnQcC064Bkfw==", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/inferno-hydrate/-/inferno-hydrate-8.2.3.tgz", + "integrity": "sha512-AyCiswnjYg7D9veJdjiQg06Npp0/iXKhwOm2hjoY3cjadT3fIdz2XtDElLB7imU4icuJ3xOmXA8FgIfnSJfHrQ==", "license": "MIT", "dependencies": { - "inferno": "7.4.11" + "inferno": "8.2.3" } }, - "node_modules/inferno-shared": { - "version": "7.4.11", - "resolved": "https://registry.npmjs.org/inferno-shared/-/inferno-shared-7.4.11.tgz", - "integrity": "sha512-pN725bDSTxkQmRS3e/3H02/xAqgHl+xgddCMjPm8M0etRdRcVCisi3NGPhzSbDDmiftrxhY31exs7+dwsngcDA==", - "license": "MIT" - }, "node_modules/inferno-vnode-flags": { - "version": "7.4.11", - "resolved": "https://registry.npmjs.org/inferno-vnode-flags/-/inferno-vnode-flags-7.4.11.tgz", - "integrity": "sha512-L7lslEQCq3IfwgT/b9zhuMf8fv6KXCNXXHZevk/WYxnqJsOWGDcKpJn0zkzXfvmj0otbB149iLUQVBq3oe2sfA==", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/inferno-vnode-flags/-/inferno-vnode-flags-8.2.3.tgz", + "integrity": "sha512-dfC0MIwFv9PCbZCUsuk9ISejFS3fKJODC0rZ/LjxxzE+OrCk+PMwPLsUnGU6O9/jbBnPACVz1BkACDf5LWgU5Q==", "license": "MIT" }, "node_modules/inflight": { @@ -7908,9 +7903,9 @@ } }, "node_modules/postcss": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz", - "integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ { @@ -10278,24 +10273,24 @@ } }, "node_modules/vite": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", - "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.2.tgz", + "integrity": "sha512-hxdyZDY1CM6SNpKI4w4lcUc3Mtkd9ej4ECWVHSMrOdSinVc2zYOAppHeGc/hzmRo3pxM5blMzkuWHOJA/3NiFw==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", - "fdir": "^6.4.4", + "fdir": "^6.4.6", "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" + "postcss": "^8.5.6", + "rollup": "^4.40.0", + "tinyglobby": "^0.2.14" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -10304,14 +10299,14 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", - "less": "*", + "less": "^4.0.0", "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" @@ -10866,9 +10861,9 @@ } }, "node_modules/vite/node_modules/fdir": { - "version": "6.4.5", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.5.tgz", - "integrity": "sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", "dev": true, "license": "MIT", "peerDependencies": { diff --git a/React/package.json b/React/package.json index 21f61bb..e3d7de5 100644 --- a/React/package.json +++ b/React/package.json @@ -15,8 +15,8 @@ }, "dependencies": { - "devextreme": "^24.2.3", - "devextreme-react": "^24.2.3", + "devextreme": "^25.1.3", + "devextreme-react": "^25.1.3", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -48,7 +48,7 @@ "stylelint-config-standard": "^33.0.0", "typescript": "~5.8.2", "typescript-eslint": "^8.18.2", - "vite": "^6.3.5", + "vite": "^7.0.0", "ts-node": "10.9.2", "vitest": "^1.5.0" } diff --git a/React/src/App.tsx b/React/src/App.tsx index c61a5cb..2512db5 100644 --- a/React/src/App.tsx +++ b/React/src/App.tsx @@ -1,17 +1,106 @@ -import { useCallback, useState } from 'react'; import './App.css'; + import 'devextreme/dist/css/dx.material.blue.light.compact.css'; -import Button from 'devextreme-react/button'; +import { + BackgroundColor, + Chart, + CommonPaneSettings, + ConstantLine, + Label, + Series, + Tooltip, + ValueAxis, +} from 'devextreme-react/chart'; +import { registerGradient } from 'devextreme-react/common/charts'; +import { formatNumber } from 'devextreme/localization'; + +const chartData = [ + { month: 'January', targetSpend: 12000, actualSpend: 9500 }, + { month: 'February', targetSpend: 15500, actualSpend: 16500 }, + { month: 'March', targetSpend: 13500, actualSpend: 12000 }, + { month: 'April', targetSpend: 16000, actualSpend: 14000 }, + { month: 'May', targetSpend: 17000, actualSpend: 18500 }, + { month: 'June', targetSpend: 20000, actualSpend: 17500 }, + { month: 'July', targetSpend: 14500, actualSpend: 11000 }, + { month: 'August', targetSpend: 21000, actualSpend: 22500 }, + { month: 'September', targetSpend: 19000, actualSpend: 18000 }, + { month: 'October', targetSpend: 22000, actualSpend: 25000 }, + { month: 'November', targetSpend: 16000, actualSpend: 14500 }, + { month: 'December', targetSpend: 25000, actualSpend: 27000 }, +]; + +function calculateAverageSpend(): number { + const sum = chartData.reduce((accumulator, { actualSpend }) => accumulator + actualSpend, 0); + + return sum / chartData.length; +} + +const averageSpend = calculateAverageSpend(); + +function customizeTooltip(data: { value: number; seriesName: string }): { text: string } { + if (data.seriesName === 'Budget') { + return { text: formatNumber(data.value, 'currency') }; + } + const isValueAboveAverage = data.value > calculateAverageSpend(); + if (isValueAboveAverage) { + return { text: `${formatNumber(data.value, 'currency')}\n${formatNumber(data.value - averageSpend, 'currency')} above average spending.` }; + } + + return { text: `${formatNumber(data.value, 'currency')}\n${formatNumber(averageSpend - data.value, 'currency')} below average spending.` }; +} + +const chartGradient = registerGradient('linear', { + colors: [{ + offset: '20%', + color: '#dee4ff', + }, { + offset: '90%', + color: '#ffdeff', + }], +}); function App(): JSX.Element { - var [count, setCount] = useState(0); - const clickHandler = useCallback(() => { - setCount((prev) => prev + 1); - }, [setCount]); return ( -
-
+ <> + + + + + + + + + + + + + + ); }