From 72521c2d5ea99ca849e20085d6fd8c93f38faf79 Mon Sep 17 00:00:00 2001 From: Arman Boyakhchyan Date: Tue, 8 Jul 2025 10:07:42 +0400 Subject: [PATCH 1/6] Add Angular --- Angular/package-lock.json | 175 ++++++++++++++++------------- Angular/package.json | 4 +- Angular/src/app/app.component.html | 39 ++++++- Angular/src/app/app.component.ts | 50 +++++++-- Angular/src/app/app.module.ts | 4 +- 5 files changed, 184 insertions(+), 88 deletions(-) diff --git a/Angular/package-lock.json b/Angular/package-lock.json index e170a96..ea238c1 100644 --- a/Angular/package-lock.json +++ b/Angular/package-lock.json @@ -16,8 +16,8 @@ "@angular/platform-browser": "^18.0.3", "@angular/platform-browser-dynamic": "^18.0.3", "@angular/router": "^18.0.3", - "devextreme": "24.2.3", - "devextreme-angular": "24.2.3", + "devextreme": "25.1.3", + "devextreme-angular": "25.1.3", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.14.7" @@ -439,9 +439,9 @@ } }, "node_modules/@angular-devkit/core": { - "version": "17.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.8.tgz", - "integrity": "sha512-Q8q0voCGudbdCgJ7lXdnyaxKHbNQBARH68zPQV72WT8NWy+Gw/tys870i6L58NWbBaCJEUcIj/kb6KoakSRu+Q==", + "version": "17.3.11", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.11.tgz", + "integrity": "sha512-vTNDYNsLIWpYk2I969LMQFH29GTsLzxNk/0cLw5q56ARF0v5sIWfHYwGTS88jdDqIpuuettcSczbxeA7EuAmqQ==", "license": "MIT", "dependencies": { "ajv": "8.12.0", @@ -3008,16 +3008,6 @@ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", "license": "0BSD" }, - "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==", - "dependencies": { - "inferno": "^7.4.6", - "inferno-create-element": "^7.4.6", - "inferno-hydrate": "^7.4.6" - } - }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -3815,6 +3805,16 @@ "node": ">=14" } }, + "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/@rollup/rollup-win32-x64-msvc": { "version": "4.18.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", @@ -6067,10 +6067,11 @@ } }, "node_modules/core-js": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", - "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", + "version": "3.44.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.44.0.tgz", + "integrity": "sha512-aFCtd4l6GvAXwVEh3XbbVqJGHDJt0OZRa+5ePGx3LLwi12WfexqQxcsohb2wgsa/92xtl19Hd66G/L+TaAxDMw==", "hasInstallScript": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" @@ -6347,6 +6348,12 @@ "node": ">=4" } }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, "node_modules/custom-event": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", @@ -6628,9 +6635,9 @@ "dev": true }, "node_modules/devexpress-diagram": { - "version": "2.2.13", - "resolved": "https://registry.npmjs.org/devexpress-diagram/-/devexpress-diagram-2.2.13.tgz", - "integrity": "sha512-OfAcfcFWJYlU/1kMtqrSSQUY3GQWKPHqU27A9e+TzFEhxI8XDyIPOCOnslRxnzYkfhB/RZ7hbGv9U0aHmtVbRg==", + "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", @@ -6638,9 +6645,9 @@ } }, "node_modules/devexpress-gantt": { - "version": "4.1.56", - "resolved": "https://registry.npmjs.org/devexpress-gantt/-/devexpress-gantt-4.1.56.tgz", - "integrity": "sha512-jnnvDYDDzjqr8pnWYsAM96mug6yXEQ1H26QLLBRbwLC72ckb1yv0Rk6DUae9ZwewIFNzIKHt1klQMF/KD9Mb8A==", + "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", @@ -6654,47 +6661,52 @@ "license": "0BSD" }, "node_modules/devextreme": { - "version": "24.2.3", - "resolved": "https://registry.npmjs.org/devextreme/-/devextreme-24.2.3.tgz", - "integrity": "sha512-5KdXaZWLOhlncS26U8G9q5QpoO7gTluJfoUjgB74NN2Pe0S8yX0YAXylx5CqbEh1w2MjNfIU36fuFn2zwGP/nQ==", + "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.13", - "devexpress-gantt": "4.1.56", - "devextreme-quill": "1.7.1", - "inferno": "^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" + }, + "bin": { + "devextreme-bundler": "bin/bundler.js", + "devextreme-bundler-init": "bin/bundler-init.js" } }, "node_modules/devextreme-angular": { - "version": "24.2.3", - "resolved": "https://registry.npmjs.org/devextreme-angular/-/devextreme-angular-24.2.3.tgz", - "integrity": "sha512-lDdTJhIIxCmMPTJfolIBqLjz2ixPQgHtJdS+qU6LtdxdR1Y9egwsq7E0VvzBTXo5T4h25FSXixxuWGGmo9k8bA==", + "version": "25.1.3", + "resolved": "https://registry.npmjs.org/devextreme-angular/-/devextreme-angular-25.1.3.tgz", + "integrity": "sha512-hLUuv/x5Gw8WZTLVvb5cI8OzXhFrgL5FRJhszR/7KgVxsPX/5qaqp1L98bhHrCYQ6QguAl9bEBX2nG516Q4fsQ==", "license": "MIT", "dependencies": { - "@angular-devkit/schematics": "17.3.8", + "@angular-devkit/schematics": "17.3.11", "devextreme-schematics": "*", - "inferno-server": "7.4.11", + "inferno-server": "^8.2.3", "tslib": "^2.3.0" }, "peerDependencies": { "@angular/common": ">=17.0.0", "@angular/core": ">=17.0.0", "@angular/forms": ">=17.0.0", - "devextreme": "~24.2.3" + "devextreme": "25.1.3" } }, "node_modules/devextreme-angular/node_modules/@angular-devkit/schematics": { - "version": "17.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.3.8.tgz", - "integrity": "sha512-QRVEYpIfgkprNHc916JlPuNbLzOgrm9DZalHasnLUz4P6g7pR21olb8YCyM2OTJjombNhya9ZpckcADU5Qyvlg==", + "version": "17.3.11", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.3.11.tgz", + "integrity": "sha512-I5wviiIqiFwar9Pdk30Lujk8FczEEc18i22A5c6Z9lbmhPQdTroDnEQdsfXjy404wPe8H62s0I15o4pmMGfTYQ==", "license": "MIT", "dependencies": { - "@angular-devkit/core": "17.3.8", + "@angular-devkit/core": "17.3.11", "jsonc-parser": "3.2.1", "magic-string": "0.30.8", "ora": "5.4.1", @@ -6707,14 +6719,14 @@ } }, "node_modules/devextreme-quill": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/devextreme-quill/-/devextreme-quill-1.7.1.tgz", - "integrity": "sha512-0smNE/Br+m9gQDxSPaJxwmrX5ZFubnBHWdbBtY8p6L3ATrF00mFqNQIflVi1tUAr8ndYeHY6Oih46Z1EWDGSQA==", + "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" @@ -8345,7 +8357,8 @@ "node_modules/fast-diff": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==" + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "license": "Apache-2.0" }, "node_modules/fast-glob": { "version": "3.3.2", @@ -9407,52 +9420,56 @@ } }, "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-server": { - "version": "7.4.11", - "resolved": "https://registry.npmjs.org/inferno-server/-/inferno-server-7.4.11.tgz", - "integrity": "sha512-SUnkCqZNWOIrjRVoVk/E1/70O1f1ImkCX9H2gDPbS0uc3GDxuzIeCgn0rpcc0XV9KzZJ2LTGxuBtEoQQOjUn2Q==", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/inferno-server/-/inferno-server-8.2.3.tgz", + "integrity": "sha512-swaDCaTYPplKwcBDbveu7xKIAooLXOOdfRoETTCIZwKyfKBGR3JnqsrwcL6miFR8TG6CNibvYKG8eSYHzkoA4Q==", + "license": "MIT", "dependencies": { - "inferno": "7.4.11" + "inferno": "8.2.3" }, "engines": { "node": ">=8" } }, - "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==" - }, "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": { "version": "1.0.6", @@ -10927,7 +10944,8 @@ "node_modules/lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", @@ -10938,7 +10956,9 @@ "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -12323,6 +12343,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", + "license": "MIT", "bin": { "opencollective-postinstall": "index.js" } @@ -12567,7 +12588,8 @@ "node_modules/parchment": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/parchment/-/parchment-2.0.1.tgz", - "integrity": "sha512-VBKrlEoZCBD+iwoeag0QTtY1Cti+Ma4nLpVYcc/uus/wHhMsPOi5InH3RL1s4aekahPZpabcS2ToKyGf7RMH/g==" + "integrity": "sha512-VBKrlEoZCBD+iwoeag0QTtY1Cti+Ma4nLpVYcc/uus/wHhMsPOi5InH3RL1s4aekahPZpabcS2ToKyGf7RMH/g==", + "license": "BSD-3-Clause" }, "node_modules/parent-module": { "version": "1.0.1", @@ -13283,6 +13305,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz", "integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==", + "license": "MIT", "dependencies": { "fast-diff": "^1.3.0", "lodash.clonedeep": "^4.5.0", diff --git a/Angular/package.json b/Angular/package.json index 13457a3..5549641 100644 --- a/Angular/package.json +++ b/Angular/package.json @@ -22,8 +22,8 @@ "@angular/platform-browser": "^18.0.3", "@angular/platform-browser-dynamic": "^18.0.3", "@angular/router": "^18.0.3", - "devextreme": "24.2.3", - "devextreme-angular": "24.2.3", + "devextreme": "25.1.3", + "devextreme-angular": "25.1.3", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.14.7" diff --git a/Angular/src/app/app.component.html b/Angular/src/app/app.component.html index 0f59cbc..cb243b9 100644 --- a/Angular/src/app/app.component.html +++ b/Angular/src/app/app.component.html @@ -1,3 +1,40 @@
- + + + + + + + + + + + + +
diff --git a/Angular/src/app/app.component.ts b/Angular/src/app/app.component.ts index 9e09ad6..9b8c77a 100644 --- a/Angular/src/app/app.component.ts +++ b/Angular/src/app/app.component.ts @@ -1,5 +1,7 @@ import { Component } from '@angular/core'; -import { ClickEvent } from 'devextreme/ui/button'; + +import { registerGradient } from 'devextreme-angular/common/charts'; +import { formatNumber } from 'devextreme/localization'; @Component({ selector: 'app-root', @@ -7,14 +9,48 @@ import { ClickEvent } from 'devextreme/ui/button'; styleUrls: ['./app.component.scss'], }) export class AppComponent { - title = 'Angular'; + 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 }, + ]; + + chartGradient = registerGradient('linear', { + colors: [{ + offset: '20%', + color: '#dee4ff', + }, { + offset: '90%', + color: '#ffdeff', + }], + }); - counter = 0; + // Type () => number (returned by calculateAverageSpend()) cannot be directly assigned to the value property of the dxi-constant-line selector. + averageSpend = this.calculateAverageSpend(); - buttonText = 'Click count: 0'; + calculateAverageSpend(): number { + let sum = 0; - onClick(e: ClickEvent): void { - this.counter++; - this.buttonText = `Click count: ${this.counter}`; + this.chartData.forEach((data) => { + sum += data.actualSpend; + }); + + return sum / this.chartData.length; } + + customizeTooltip: (data: { value: number }) => { text: string } = (data: { value: number }) => { + const isValueAboveAverage = data.value > this.averageSpend; + const aboveText = `${formatNumber(data.value, 'currency')}\n${formatNumber(data.value - this.averageSpend, 'currency')} above average spending.`; + const belowText = `${formatNumber(data.value, 'currency')}\n${formatNumber(this.averageSpend - data.value, 'currency')} below average spending.`; + return { text: isValueAboveAverage ? aboveText : belowText }; + }; } diff --git a/Angular/src/app/app.module.ts b/Angular/src/app/app.module.ts index b9e30aa..85028a7 100644 --- a/Angular/src/app/app.module.ts +++ b/Angular/src/app/app.module.ts @@ -1,6 +1,6 @@ import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; -import { DxButtonModule } from 'devextreme-angular/ui/button'; +import { DxChartModule } from 'devextreme-angular/ui/chart'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @@ -11,7 +11,7 @@ import { AppComponent } from './app.component'; imports: [ BrowserModule, AppRoutingModule, - DxButtonModule, + DxChartModule, ], providers: [], bootstrap: [AppComponent], From 36c4bb7a7a79451b45ac3a11a1a761d7c4a7fe85 Mon Sep 17 00:00:00 2001 From: DevExpressExampleBot Date: Tue, 8 Jul 2025 10:20:11 +0400 Subject: [PATCH 2/6] README auto update [skip ci] --- README.md | 1 - 1 file changed, 1 deletion(-) 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) From 9b981afc254132762370ad9d395b6db0230b1043 Mon Sep 17 00:00:00 2001 From: Arman Boyakhchyan Date: Tue, 8 Jul 2025 12:04:35 +0400 Subject: [PATCH 3/6] Update tooltip --- Angular/src/app/app.component.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Angular/src/app/app.component.ts b/Angular/src/app/app.component.ts index 9b8c77a..07cd10d 100644 --- a/Angular/src/app/app.component.ts +++ b/Angular/src/app/app.component.ts @@ -47,7 +47,10 @@ export class AppComponent { return sum / this.chartData.length; } - customizeTooltip: (data: { value: number }) => { text: string } = (data: { value: number }) => { + customizeTooltip: (data: { value: number, seriesName: string }) => { text: string } = (data: { value: number, seriesName: string }) => { + if (data.seriesName === "Budget") { + return { text: formatNumber(data.value, 'currency') } + } const isValueAboveAverage = data.value > this.averageSpend; const aboveText = `${formatNumber(data.value, 'currency')}\n${formatNumber(data.value - this.averageSpend, 'currency')} above average spending.`; const belowText = `${formatNumber(data.value, 'currency')}\n${formatNumber(this.averageSpend - data.value, 'currency')} below average spending.`; From d907bd942b17cb4bac4624b116f39698a9deec43 Mon Sep 17 00:00:00 2001 From: Arman Boyakhchyan Date: Tue, 8 Jul 2025 12:07:53 +0400 Subject: [PATCH 4/6] Fix linting --- Angular/src/app/app.component.html | 2 +- Angular/src/app/app.component.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Angular/src/app/app.component.html b/Angular/src/app/app.component.html index cb243b9..4bc9f20 100644 --- a/Angular/src/app/app.component.html +++ b/Angular/src/app/app.component.html @@ -14,7 +14,7 @@ type="spline" argumentField="month" valueField="actualSpend" - name="Amount Spend" + name="Amount Spent" color="#cb4bfa" > diff --git a/Angular/src/app/app.component.ts b/Angular/src/app/app.component.ts index 07cd10d..a919c25 100644 --- a/Angular/src/app/app.component.ts +++ b/Angular/src/app/app.component.ts @@ -47,9 +47,9 @@ export class AppComponent { return sum / this.chartData.length; } - customizeTooltip: (data: { value: number, seriesName: string }) => { text: string } = (data: { value: number, seriesName: string }) => { - if (data.seriesName === "Budget") { - return { text: formatNumber(data.value, 'currency') } + customizeTooltip: (data: { value: number; seriesName: string }) => { text: string } = (data: { value: number; seriesName: string }) => { + if (data.seriesName === 'Budget') { + return { text: formatNumber(data.value, 'currency') }; } const isValueAboveAverage = data.value > this.averageSpend; const aboveText = `${formatNumber(data.value, 'currency')}\n${formatNumber(data.value - this.averageSpend, 'currency')} above average spending.`; From c38d6a243294f51d0afca5054bd8a12d761e152f Mon Sep 17 00:00:00 2001 From: Arman Boyakhchyan Date: Wed, 9 Jul 2025 09:54:32 +0400 Subject: [PATCH 5/6] Update following feedback --- Angular/src/app/app.component.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Angular/src/app/app.component.ts b/Angular/src/app/app.component.ts index a919c25..29c18c4 100644 --- a/Angular/src/app/app.component.ts +++ b/Angular/src/app/app.component.ts @@ -38,11 +38,7 @@ export class AppComponent { averageSpend = this.calculateAverageSpend(); calculateAverageSpend(): number { - let sum = 0; - - this.chartData.forEach((data) => { - sum += data.actualSpend; - }); + const sum = this.chartData.reduce((accumulator, { actualSpend }) => accumulator + actualSpend, 0); return sum / this.chartData.length; } From a4bee46a51640fbe7265c08f840f997339b91076 Mon Sep 17 00:00:00 2001 From: Arman Boyakhchyan Date: Wed, 9 Jul 2025 13:15:44 +0400 Subject: [PATCH 6/6] Update customizeTooltip --- Angular/src/app/app.component.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Angular/src/app/app.component.ts b/Angular/src/app/app.component.ts index 29c18c4..83e6148 100644 --- a/Angular/src/app/app.component.ts +++ b/Angular/src/app/app.component.ts @@ -48,8 +48,10 @@ export class AppComponent { return { text: formatNumber(data.value, 'currency') }; } const isValueAboveAverage = data.value > this.averageSpend; - const aboveText = `${formatNumber(data.value, 'currency')}\n${formatNumber(data.value - this.averageSpend, 'currency')} above average spending.`; - const belowText = `${formatNumber(data.value, 'currency')}\n${formatNumber(this.averageSpend - data.value, 'currency')} below average spending.`; - return { text: isValueAboveAverage ? aboveText : belowText }; + if (isValueAboveAverage) { + return { text: `${formatNumber(data.value, 'currency')}\n${formatNumber(data.value - this.averageSpend, 'currency')} above average spending.` }; + } + + return { text: `${formatNumber(data.value, 'currency')}\n${formatNumber(this.averageSpend - data.value, 'currency')} below average spending.` }; }; }