From 8ccd8aa868cbf0b840287be39cb960a725d3deb9 Mon Sep 17 00:00:00 2001 From: Kristin Bradley Date: Wed, 6 Aug 2025 16:13:11 -0700 Subject: [PATCH 1/8] HDS-5289 Add basic example donut chart using Carbon Charts DonutChart --- packages/components/package.json | 4 + .../src/components/hds/charts/donut/data.js | 26 + .../src/components/hds/charts/donut/index.hbs | 6 + .../src/components/hds/charts/donut/index.ts | 33 + .../components/hds/charts/donut/options.js | 17 + .../@hashicorp/design-system-components.scss | 1 + .../src/styles/components/charts/donut.scss | 13 + pnpm-lock.yaml | 679 ++++++++++++++++++ showcase/app/router.ts | 21 +- .../app/routes/components/charts/donut.js | 8 + showcase/app/templates/index.hbs | 12 + .../page-components/charts/donut.hbs | 14 + .../acceptance/components/hds/charts/donut.js | 21 + showcase/tests/acceptance/percy-test.js | 3 + .../components/hds/charts/donut/index-test.js | 18 + 15 files changed, 867 insertions(+), 9 deletions(-) create mode 100644 packages/components/src/components/hds/charts/donut/data.js create mode 100644 packages/components/src/components/hds/charts/donut/index.hbs create mode 100644 packages/components/src/components/hds/charts/donut/index.ts create mode 100644 packages/components/src/components/hds/charts/donut/options.js create mode 100644 packages/components/src/styles/components/charts/donut.scss create mode 100644 showcase/app/routes/components/charts/donut.js create mode 100644 showcase/app/templates/page-components/charts/donut.hbs create mode 100644 showcase/tests/acceptance/components/hds/charts/donut.js create mode 100644 showcase/tests/integration/components/hds/charts/donut/index-test.js diff --git a/packages/components/package.json b/packages/components/package.json index 7a0105f3e6f..e379e2071cf 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -33,6 +33,7 @@ "prepublishOnly": "pnpm build && test -f 'dist/styles/@hashicorp/design-system-components.css' || (echo 'The pre-compiled CSS file was not found' && exit 1)" }, "dependencies": { + "@carbon/charts": "1.23.15", "@codemirror/commands": "^6.8.0", "@codemirror/lang-go": "^6.0.1", "@codemirror/lang-javascript": "^6.2.2", @@ -199,6 +200,9 @@ "./components/hds/button-set/index.js": "./dist/_app_/components/hds/button-set/index.js", "./components/hds/button/index.js": "./dist/_app_/components/hds/button/index.js", "./components/hds/card/container.js": "./dist/_app_/components/hds/card/container.js", + "./components/hds/charts/donut/data.js": "./dist/_app_/components/hds/charts/donut/data.js", + "./components/hds/charts/donut/index.js": "./dist/_app_/components/hds/charts/donut/index.js", + "./components/hds/charts/donut/options.js": "./dist/_app_/components/hds/charts/donut/options.js", "./components/hds/code-block/copy-button.js": "./dist/_app_/components/hds/code-block/copy-button.js", "./components/hds/code-block/description.js": "./dist/_app_/components/hds/code-block/description.js", "./components/hds/code-block/index.js": "./dist/_app_/components/hds/code-block/index.js", diff --git a/packages/components/src/components/hds/charts/donut/data.js b/packages/components/src/components/hds/charts/donut/data.js new file mode 100644 index 00000000000..5b0c5a8e539 --- /dev/null +++ b/packages/components/src/components/hds/charts/donut/data.js @@ -0,0 +1,26 @@ +export default [ + { + group: '2V2N 9KYPM version 1', + value: 20000, + }, + { + group: 'L22I P66EP L22I P66EP L22I P66EP', + value: 65000, + }, + { + group: 'JQAI 2M4L1', + value: 75000, + }, + { + group: 'J9DZ F37AP', + value: 1200, + }, + { + group: 'YEL48 Q6XK YEL48', + value: 10000, + }, + { + group: 'Misc', + value: 25000, + }, +]; diff --git a/packages/components/src/components/hds/charts/donut/index.hbs b/packages/components/src/components/hds/charts/donut/index.hbs new file mode 100644 index 00000000000..f3cb47e4e7d --- /dev/null +++ b/packages/components/src/components/hds/charts/donut/index.hbs @@ -0,0 +1,6 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} + +
\ No newline at end of file diff --git a/packages/components/src/components/hds/charts/donut/index.ts b/packages/components/src/components/hds/charts/donut/index.ts new file mode 100644 index 00000000000..61602babc9f --- /dev/null +++ b/packages/components/src/components/hds/charts/donut/index.ts @@ -0,0 +1,33 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Component from '@glimmer/component'; +import { action } from '@ember/object'; + +import { DonutChart } from '@carbon/charts'; +import options from './options.js'; +import data from './data.js'; +import '@carbon/charts/styles.css'; + +export interface HdsChartsDonutSignature { + // Args: {}; + Blocks: { + default: []; + }; + Element: HTMLDivElement; +} +// More info on types and signatures: https://hashicorp.atlassian.net/wiki/spaces/HDS/pages/3245932580/Using+Typescript + +export default class HdsChartsDonut extends Component { + chart: DonutChart | null = null; + + @action + setupChart(element: HTMLDivElement): void { + this.chart = new DonutChart(element, { + data, + options, + }); + } +} diff --git a/packages/components/src/components/hds/charts/donut/options.js b/packages/components/src/components/hds/charts/donut/options.js new file mode 100644 index 00000000000..6836823ab0f --- /dev/null +++ b/packages/components/src/components/hds/charts/donut/options.js @@ -0,0 +1,17 @@ +export default { + title: 'Donut (centered)', + resizable: true, + legend: { + position: 'right', + truncation: { + type: 'none', + }, + }, + donut: { + center: { + label: 'Browsers', + }, + alignment: 'center', + }, + height: '400px', +}; diff --git a/packages/components/src/styles/@hashicorp/design-system-components.scss b/packages/components/src/styles/@hashicorp/design-system-components.scss index 00c6008b820..9cc0969da89 100644 --- a/packages/components/src/styles/@hashicorp/design-system-components.scss +++ b/packages/components/src/styles/@hashicorp/design-system-components.scss @@ -26,6 +26,7 @@ @use "../components/button"; @use "../components/button-set"; @use "../components/card"; +@use "../components/charts/donut"; @use "../components/code-block"; @use "../components/code-editor"; @use "../components/copy"; diff --git a/packages/components/src/styles/components/charts/donut.scss b/packages/components/src/styles/components/charts/donut.scss new file mode 100644 index 00000000000..fcd37c6c587 --- /dev/null +++ b/packages/components/src/styles/components/charts/donut.scss @@ -0,0 +1,13 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +// +// CHARTS > DONUT +// + +.hds-charts-donut { + // add the component styles here + outline: 1px dotted red; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 141c7b2cafe..fb9f1a0862d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,6 +63,9 @@ importers: packages/components: dependencies: + '@carbon/charts': + specifier: 1.23.15 + version: 1.23.15 '@codemirror/commands': specifier: ^6.8.0 version: 6.8.1 @@ -1877,6 +1880,15 @@ packages: '@bundled-es-modules/memfs@4.9.4': resolution: {integrity: sha512-1XyYPUaIHwEOdF19wYVLBtHJRr42Do+3ctht17cZOHwHf67vkmRNPlYDGY2kJps4RgE5+c7nEZmEzxxvb1NZWA==} + '@carbon/charts@1.23.15': + resolution: {integrity: sha512-Q9zdXzRkKL/PRRMSnc3rA9ypyH0UejFxmN2/fS1K4o5yZb9PQkxc7cWuglI9GwAUD/ml6/clcIuLmVKnB8BFcA==} + + '@carbon/colors@11.37.0': + resolution: {integrity: sha512-PXZkIJ9AulEkiIFlI8fjaksi7tWuoPUKfChc5op55j6jP1zXTEfrb449SCKXOJM912MzY5EkaRGgNN09f6rM2Q==} + + '@carbon/utils-position@1.3.0': + resolution: {integrity: sha512-bfar2dV+fQ15syIrH3n9ujY4PXd1Q+AF2VcTLJIC04IDe2f80zOnJlLNPc/RktHcWTZ7WSQm80cQo3abGcsfTA==} + '@changesets/apply-release-plan@7.0.12': resolution: {integrity: sha512-EaET7As5CeuhTzvXTQCRZeBUcisoYPDDcXvgTE/2jmmypKp0RC7LxKj/yzqeh/1qFTZI7oDGFcL1PHRuQuketQ==} @@ -2852,6 +2864,10 @@ packages: resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} engines: {node: '>=18.18'} + '@ibm/telemetry-js@1.9.1': + resolution: {integrity: sha512-qq8RPafUJHUQieXVCte1kbJEx6JctWzbA/YkXzopbfzIDRT2+hbR9QmgH+KH7bDDNRcDbdHWvHfwJKzThlMtPg==} + hasBin: true + '@inquirer/figures@1.0.9': resolution: {integrity: sha512-BXvGj0ehzrngHTPTDqUoDT3NXL8U0RxUk2zJm2A66RhCEIWdtU1v6GuUqNAgArW4PQ9CinqIWyHdQgdwOj06zQ==} engines: {node: '>=18'} @@ -3543,6 +3559,99 @@ packages: '@types/cors@2.8.17': resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} + '@types/d3-array@3.2.1': + resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} + + '@types/d3-axis@3.0.6': + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} + + '@types/d3-brush@3.0.6': + resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} + + '@types/d3-chord@3.0.6': + resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-contour@3.0.6': + resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} + + '@types/d3-delaunay@6.0.4': + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} + + '@types/d3-dispatch@3.0.7': + resolution: {integrity: sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==} + + '@types/d3-drag@3.0.7': + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} + + '@types/d3-dsv@3.0.7': + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-fetch@3.0.7': + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} + + '@types/d3-force@3.0.10': + resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} + + '@types/d3-format@3.0.4': + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} + + '@types/d3-geo@3.1.0': + resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} + + '@types/d3-hierarchy@3.1.7': + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + + '@types/d3-polygon@3.0.2': + resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} + + '@types/d3-quadtree@3.0.6': + resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} + + '@types/d3-random@3.0.3': + resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==} + + '@types/d3-scale-chromatic@3.1.0': + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-selection@3.0.11': + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} + + '@types/d3-shape@3.1.7': + resolution: {integrity: sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==} + + '@types/d3-time-format@4.0.3': + resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + + '@types/d3-transition@3.0.9': + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} + + '@types/d3-zoom@3.0.8': + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} + + '@types/d3@7.4.3': + resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} + '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} @@ -3630,6 +3739,9 @@ packages: '@types/fs-extra@9.0.13': resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} + '@types/geojson@7946.0.16': + resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} + '@types/glob@7.2.0': resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} @@ -3768,6 +3880,24 @@ packages: '@types/tinycolor2@1.4.6': resolution: {integrity: sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw==} + '@types/topojson-client@3.1.5': + resolution: {integrity: sha512-C79rySTyPxnQNNguTZNI1Ct4D7IXgvyAs3p9HPecnl6mNrJ5+UhvGNYcZfpROYV2lMHI48kJPxwR+F9C6c7nmw==} + + '@types/topojson-server@3.0.4': + resolution: {integrity: sha512-5+ieK8ePfP+K2VH6Vgs1VCt+fO1U8XZHj0UsF+NktaF0DavAo1q3IvCBXgokk/xmtvoPltSUs6vxuR/zMdOE1g==} + + '@types/topojson-simplify@3.0.3': + resolution: {integrity: sha512-sBO5UZ0O2dB0bNwo0vut2yLHhj3neUGi9uL7/ROdm8Gs6dtt4jcB9OGDKr+M2isZwQM2RuzVmifnMZpxj4IGNw==} + + '@types/topojson-specification@1.0.5': + resolution: {integrity: sha512-C7KvcQh+C2nr6Y2Ub4YfgvWvWCgP2nOQMtfhlnwsRL4pYmmwzBS7HclGiS87eQfDOU/DLQpX6GEscviaz4yLIQ==} + + '@types/topojson@3.2.6': + resolution: {integrity: sha512-ppfdlxjxofWJ66XdLgIlER/85RvpGyfOf8jrWf+3kVIjEatFxEZYD/Ea83jO672Xu1HRzd/ghwlbcZIUNHTskw==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -5690,6 +5820,151 @@ packages: resolution: {integrity: sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==} engines: {node: '>=0.10.0'} + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + + d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + + d3-cloud@1.2.7: + resolution: {integrity: sha512-8TrgcgwRIpoZYQp7s3fGB7tATWfhckRb8KcVd1bOgqkNdkJRDGWfdSf4HkHHzZxSczwQJdSxvfPudwir5IAJ3w==} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-dispatch@1.0.6: + resolution: {integrity: sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA==} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + + d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + + d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + dag-map@2.0.2: resolution: {integrity: sha512-xnsprIzYuDeiyu5zSKwilV/ajRHxnoMlAhEREfyfTgTSViMVY2fGP1ZcHJbtwup26oCkofySU/m6oKJ3HrkW7w==} @@ -5720,6 +5995,9 @@ packages: dataloader@1.4.0: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} + date-fns@4.1.0: + resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + date-time@2.1.0: resolution: {integrity: sha512-/9+C44X7lot0IeiyfgJmETtRMhBidBYM2QFFIkGa0U1k+hSyY87Nw7PY3eDqpvCBm7I3WCSfPeZskW/YYq6m4g==} engines: {node: '>=4'} @@ -5842,6 +6120,9 @@ packages: resolution: {integrity: sha512-R6ep6JJ+eOBZsBr9esiNN1gxFbZE4Q2cULkUSFumGYecAiS6qodDvcPx/sFuWHMNul7DWmrtoEOpYSm7o6tbSA==} engines: {node: '>=18'} + delaunator@5.0.1: + resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -5962,6 +6243,9 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} + dompurify@3.2.6: + resolution: {integrity: sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==} + domutils@1.7.0: resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} @@ -7646,6 +7930,9 @@ packages: resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} engines: {node: '>=8'} + html-to-image@1.11.11: + resolution: {integrity: sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==} + html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} @@ -7839,6 +8126,13 @@ packages: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + intl-messageformat@10.7.16: resolution: {integrity: sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug==} @@ -10319,6 +10613,9 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true + robust-predicates@3.0.2: + resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + rollup-plugin-copy-assets@2.0.3: resolution: {integrity: sha512-ETShhQGb9SoiwcNrvb3BhUNSGR89Jao0+XxxfzzLW1YsUzx8+rMO4z9oqWWmo6OHUmfNQRvqRj0cAyPkS9lN9w==} peerDependencies: @@ -10381,6 +10678,9 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + rxjs@6.6.7: resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} engines: {npm: '>=2.0.0'} @@ -11215,6 +11515,10 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + topojson-client@3.1.0: + resolution: {integrity: sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==} + hasBin: true + tough-cookie@4.1.4: resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} @@ -13027,6 +13331,31 @@ snapshots: stream: 0.0.3 util: 0.12.5 + '@carbon/charts@1.23.15': + dependencies: + '@carbon/colors': 11.37.0 + '@carbon/utils-position': 1.3.0 + '@ibm/telemetry-js': 1.9.1 + '@types/d3': 7.4.3 + '@types/topojson': 3.2.6 + d3: 7.9.0 + d3-cloud: 1.2.7 + d3-sankey: 0.12.3 + date-fns: 4.1.0 + dompurify: 3.2.6 + html-to-image: 1.11.11 + lodash-es: 4.17.21 + topojson-client: 3.1.0 + tslib: 2.8.1 + + '@carbon/colors@11.37.0': + dependencies: + '@ibm/telemetry-js': 1.9.1 + + '@carbon/utils-position@1.3.0': + dependencies: + '@ibm/telemetry-js': 1.9.1 + '@changesets/apply-release-plan@7.0.12': dependencies: '@changesets/config': 3.1.1 @@ -14300,6 +14629,7 @@ snapshots: '@hashicorp/design-system-components@file:packages/components(5fea96526e38c31493053252567363c4)': dependencies: + '@carbon/charts': 1.23.15 '@codemirror/commands': 6.8.1 '@codemirror/lang-go': 6.0.1 '@codemirror/lang-javascript': 6.2.4 @@ -14358,6 +14688,7 @@ snapshots: '@hashicorp/design-system-components@file:packages/components(f62dfc5f715da30824529e0727e3c947)': dependencies: + '@carbon/charts': 1.23.15 '@codemirror/commands': 6.8.1 '@codemirror/lang-go': 6.0.1 '@codemirror/lang-javascript': 6.2.4 @@ -14441,6 +14772,8 @@ snapshots: '@humanwhocodes/retry@0.4.2': {} + '@ibm/telemetry-js@1.9.1': {} + '@inquirer/figures@1.0.9': {} '@isaacs/balanced-match@4.0.1': {} @@ -15330,6 +15663,123 @@ snapshots: dependencies: '@types/node': 24.1.0 + '@types/d3-array@3.2.1': {} + + '@types/d3-axis@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-brush@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-chord@3.0.6': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-contour@3.0.6': + dependencies: + '@types/d3-array': 3.2.1 + '@types/geojson': 7946.0.16 + + '@types/d3-delaunay@6.0.4': {} + + '@types/d3-dispatch@3.0.7': {} + + '@types/d3-drag@3.0.7': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-dsv@3.0.7': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-fetch@3.0.7': + dependencies: + '@types/d3-dsv': 3.0.7 + + '@types/d3-force@3.0.10': {} + + '@types/d3-format@3.0.4': {} + + '@types/d3-geo@3.1.0': + dependencies: + '@types/geojson': 7946.0.16 + + '@types/d3-hierarchy@3.1.7': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.1': {} + + '@types/d3-polygon@3.0.2': {} + + '@types/d3-quadtree@3.0.6': {} + + '@types/d3-random@3.0.3': {} + + '@types/d3-scale-chromatic@3.1.0': {} + + '@types/d3-scale@4.0.9': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-selection@3.0.11': {} + + '@types/d3-shape@3.1.7': + dependencies: + '@types/d3-path': 3.1.1 + + '@types/d3-time-format@4.0.3': {} + + '@types/d3-time@3.0.4': {} + + '@types/d3-timer@3.0.2': {} + + '@types/d3-transition@3.0.9': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-zoom@3.0.8': + dependencies: + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.11 + + '@types/d3@7.4.3': + dependencies: + '@types/d3-array': 3.2.1 + '@types/d3-axis': 3.0.6 + '@types/d3-brush': 3.0.6 + '@types/d3-chord': 3.0.6 + '@types/d3-color': 3.1.3 + '@types/d3-contour': 3.0.6 + '@types/d3-delaunay': 6.0.4 + '@types/d3-dispatch': 3.0.7 + '@types/d3-drag': 3.0.7 + '@types/d3-dsv': 3.0.7 + '@types/d3-ease': 3.0.2 + '@types/d3-fetch': 3.0.7 + '@types/d3-force': 3.0.10 + '@types/d3-format': 3.0.4 + '@types/d3-geo': 3.1.0 + '@types/d3-hierarchy': 3.1.7 + '@types/d3-interpolate': 3.0.4 + '@types/d3-path': 3.1.1 + '@types/d3-polygon': 3.0.2 + '@types/d3-quadtree': 3.0.6 + '@types/d3-random': 3.0.3 + '@types/d3-scale': 4.0.9 + '@types/d3-scale-chromatic': 3.1.0 + '@types/d3-selection': 3.0.11 + '@types/d3-shape': 3.1.7 + '@types/d3-time': 3.0.4 + '@types/d3-time-format': 4.0.3 + '@types/d3-timer': 3.0.2 + '@types/d3-transition': 3.0.9 + '@types/d3-zoom': 3.0.8 + '@types/debug@4.1.12': dependencies: '@types/ms': 0.7.34 @@ -15465,6 +15915,8 @@ snapshots: dependencies: '@types/node': 24.1.0 + '@types/geojson@7946.0.16': {} + '@types/glob@7.2.0': dependencies: '@types/minimatch': 5.1.2 @@ -15603,6 +16055,36 @@ snapshots: '@types/tinycolor2@1.4.6': {} + '@types/topojson-client@3.1.5': + dependencies: + '@types/geojson': 7946.0.16 + '@types/topojson-specification': 1.0.5 + + '@types/topojson-server@3.0.4': + dependencies: + '@types/geojson': 7946.0.16 + '@types/topojson-specification': 1.0.5 + + '@types/topojson-simplify@3.0.3': + dependencies: + '@types/geojson': 7946.0.16 + '@types/topojson-specification': 1.0.5 + + '@types/topojson-specification@1.0.5': + dependencies: + '@types/geojson': 7946.0.16 + + '@types/topojson@3.2.6': + dependencies: + '@types/geojson': 7946.0.16 + '@types/topojson-client': 3.1.5 + '@types/topojson-server': 3.0.4 + '@types/topojson-simplify': 3.0.3 + '@types/topojson-specification': 1.0.5 + + '@types/trusted-types@2.0.7': + optional: true + '@types/unist@2.0.11': {} '@types/unist@3.0.3': {} @@ -18266,6 +18748,179 @@ snapshots: dependencies: array-find-index: 1.0.2 + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-axis@3.0.0: {} + + d3-brush@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3-chord@3.0.1: + dependencies: + d3-path: 3.1.0 + + d3-cloud@1.2.7: + dependencies: + d3-dispatch: 1.0.6 + + d3-color@3.1.0: {} + + d3-contour@4.0.2: + dependencies: + d3-array: 3.2.4 + + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.0.1 + + d3-dispatch@1.0.6: {} + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-format@3.1.0: {} + + d3-geo@3.1.1: + dependencies: + d3-array: 3.2.4 + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-polygon@3.0.1: {} + + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3@7.9.0: + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.0 + d3-geo: 3.1.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + dag-map@2.0.2: {} data-uri-to-buffer@6.0.2: {} @@ -18301,6 +18956,8 @@ snapshots: dataloader@1.4.0: {} + date-fns@4.1.0: {} + date-time@2.1.0: dependencies: time-zone: 1.0.0 @@ -18410,6 +19067,10 @@ snapshots: p-map: 7.0.3 slash: 5.1.0 + delaunator@5.0.1: + dependencies: + robust-predicates: 3.0.2 + delayed-stream@1.0.0: {} delegate@3.2.0: {} @@ -18506,6 +19167,10 @@ snapshots: dependencies: domelementtype: 2.3.0 + dompurify@3.2.6: + optionalDependencies: + '@types/trusted-types': 2.0.7 + domutils@1.7.0: dependencies: dom-serializer: 0.2.2 @@ -21953,6 +22618,8 @@ snapshots: html-tags@3.3.1: {} + html-to-image@1.11.11: {} + html-void-elements@3.0.0: {} htmlparser2@3.10.1: @@ -22183,6 +22850,10 @@ snapshots: hasown: 2.0.2 side-channel: 1.1.0 + internmap@1.0.1: {} + + internmap@2.0.3: {} + intl-messageformat@10.7.16: dependencies: '@formatjs/ecma402-abstract': 2.3.4 @@ -25137,6 +25808,8 @@ snapshots: dependencies: glob: 7.2.3 + robust-predicates@3.0.2: {} + rollup-plugin-copy-assets@2.0.3(rollup@4.46.2): dependencies: fs-extra: 7.0.1 @@ -25224,6 +25897,8 @@ snapshots: dependencies: queue-microtask: 1.2.3 + rw@1.3.3: {} + rxjs@6.6.7: dependencies: tslib: 1.14.1 @@ -26374,6 +27049,10 @@ snapshots: toidentifier@1.0.1: {} + topojson-client@3.1.0: + dependencies: + commander: 2.20.3 + tough-cookie@4.1.4: dependencies: psl: 1.15.0 diff --git a/showcase/app/router.ts b/showcase/app/router.ts index d6b68629d80..7ba562963e2 100644 --- a/showcase/app/router.ts +++ b/showcase/app/router.ts @@ -11,31 +11,31 @@ export default class Router extends EmberRouter { rootURL = config.rootURL; } -Router.map(function () { - this.route('page-foundations', { path: 'foundations' }, function () { +Router.map(function (): void { + this.route('page-foundations', { path: 'foundations' }, function (): void { this.route('typography'); this.route('elevation'); this.route('focus-ring'); - this.route('breakpoints', function () { - this.route('frameless', function () { + this.route('breakpoints', function (): void { + this.route('frameless', function (): void { this.route('demo-viewport-breakpoints-visualization'); this.route('demo-viewport-breakpoints-visualization-with-ui-shell'); this.route('demo-viewport-breakpoints-page-padding'); }); }); }); - this.route('page-components', { path: 'components' }, function () { + this.route('page-components', { path: 'components' }, function (): void { this.route('accordion'); this.route('advanced-table'); this.route('alert'); this.route('app-footer'); - this.route('app-header', function () { - this.route('frameless', function () { + this.route('app-header', function (): void { + this.route('frameless', function (): void { this.route('demo-responsiveness'); }); }); - this.route('app-side-nav', function () { - this.route('frameless', function () { + this.route('app-side-nav', function (): void { + this.route('frameless', function (): void { this.route('demo-responsiveness'); }); }); @@ -46,6 +46,9 @@ Router.map(function () { this.route('button'); this.route('button-set'); this.route('card'); + this.route('charts', function (): void { + this.route('donut'); + }); this.route('code-block'); this.route('code-editor'); this.route('dropdown'); diff --git a/showcase/app/routes/components/charts/donut.js b/showcase/app/routes/components/charts/donut.js new file mode 100644 index 00000000000..7b43e15a69a --- /dev/null +++ b/showcase/app/routes/components/charts/donut.js @@ -0,0 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Route from '@ember/routing/route'; + +export default class PageComponentsChartsDonutRoute extends Route {} diff --git a/showcase/app/templates/index.hbs b/showcase/app/templates/index.hbs index 763c9df7b74..c0b60893282 100644 --- a/showcase/app/templates/index.hbs +++ b/showcase/app/templates/index.hbs @@ -37,6 +37,18 @@ + + Explorations + + Carbon Charts + +
    +
  1. + + Charts / Donut + +
  2. +
diff --git a/showcase/app/templates/page-components/charts/donut.hbs b/showcase/app/templates/page-components/charts/donut.hbs new file mode 100644 index 00000000000..a4aa6239c29 --- /dev/null +++ b/showcase/app/templates/page-components/charts/donut.hbs @@ -0,0 +1,14 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} + +{{page-title "Charts::Donut Component"}} + +Charts::Donut + +Carbon Charts test + +
+ +
\ No newline at end of file diff --git a/showcase/tests/acceptance/components/hds/charts/donut.js b/showcase/tests/acceptance/components/hds/charts/donut.js new file mode 100644 index 00000000000..2b4bb04f129 --- /dev/null +++ b/showcase/tests/acceptance/components/hds/charts/donut.js @@ -0,0 +1,21 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { visit } from '@ember/test-helpers'; +import { setupApplicationTest } from 'showcase/tests/helpers'; +import { a11yAudit } from 'ember-a11y-testing/test-support'; + +module('Acceptance | components/charts/donut', function (hooks) { + setupApplicationTest(hooks); + + test('Components/charts/donut page passes automated a11y checks', async function (assert) { + await visit('/components/charts/donut'); + + await a11yAudit(); + + assert.ok(true, 'a11y automation audit passed'); + }); +}); diff --git a/showcase/tests/acceptance/percy-test.js b/showcase/tests/acceptance/percy-test.js index f446348071f..567e18bc972 100644 --- a/showcase/tests/acceptance/percy-test.js +++ b/showcase/tests/acceptance/percy-test.js @@ -84,6 +84,9 @@ module('Acceptance | Percy test', function (hooks) { await visit('/components/card'); await percySnapshot('Card'); + await visit('/components/charts-donut'); + await percySnapshot('Charts/donut'); + await visit('/components/code-block'); await percySnapshot('CodeBlock'); diff --git a/showcase/tests/integration/components/hds/charts/donut/index-test.js b/showcase/tests/integration/components/hds/charts/donut/index-test.js new file mode 100644 index 00000000000..45118ae5f59 --- /dev/null +++ b/showcase/tests/integration/components/hds/charts/donut/index-test.js @@ -0,0 +1,18 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'showcase/tests/helpers'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | hds/charts/donut/index', function (hooks) { + setupRenderingTest(hooks); + + test('it should render the component with a CSS class that matches the component name', async function (assert) { + await render(hbs``); + assert.dom('#test-charts-donut').hasClass('hds-charts-donut'); + }); +}); From 9cce992b54fdbab624d0abb3427e50ec3909f47d Mon Sep 17 00:00:00 2001 From: Kristin Bradley Date: Thu, 7 Aug 2025 17:06:50 -0700 Subject: [PATCH 2/8] HDS-5289 Add data sets and examples similar to Cloud-ui charts --- .../src/components/hds/charts/donut/data.js | 2 +- .../src/components/hds/charts/donut/index.ts | 17 ++++++-- .../components/hds/charts/donut/options.js | 27 ++++++++++++ .../src/styles/components/charts/donut.scss | 14 ++++++- .../app/routes/components/charts/donut.js | 8 ---- .../routes/page-components/charts/donut.js | 42 +++++++++++++++++++ .../page-components/charts/donut.hbs | 23 +++++++++- 7 files changed, 118 insertions(+), 15 deletions(-) delete mode 100644 showcase/app/routes/components/charts/donut.js create mode 100644 showcase/app/routes/page-components/charts/donut.js diff --git a/packages/components/src/components/hds/charts/donut/data.js b/packages/components/src/components/hds/charts/donut/data.js index 5b0c5a8e539..c5870de558a 100644 --- a/packages/components/src/components/hds/charts/donut/data.js +++ b/packages/components/src/components/hds/charts/donut/data.js @@ -1,6 +1,6 @@ export default [ { - group: '2V2N 9KYPM version 1', + group: '2V2N 9KYPM version 1', // group = label/category value: 20000, }, { diff --git a/packages/components/src/components/hds/charts/donut/index.ts b/packages/components/src/components/hds/charts/donut/index.ts index 61602babc9f..6b7da21603f 100644 --- a/packages/components/src/components/hds/charts/donut/index.ts +++ b/packages/components/src/components/hds/charts/donut/index.ts @@ -12,7 +12,10 @@ import data from './data.js'; import '@carbon/charts/styles.css'; export interface HdsChartsDonutSignature { - // Args: {}; + Args: { + title?: string; + data?: Array<{ group: string; value: number }>; + }; Blocks: { default: []; }; @@ -25,9 +28,17 @@ export default class HdsChartsDonut extends Component { @action setupChart(element: HTMLDivElement): void { + const chartData = this.args.data || data; + + // Merge the dynamic title into the options + const chartOptions = { + ...options, + title: this.args.title || options.title, // Use the passed title or fallback to the default + }; + this.chart = new DonutChart(element, { - data, - options, + data: chartData, + options: chartOptions, }); } } diff --git a/packages/components/src/components/hds/charts/donut/options.js b/packages/components/src/components/hds/charts/donut/options.js index 6836823ab0f..c76d7c004b9 100644 --- a/packages/components/src/components/hds/charts/donut/options.js +++ b/packages/components/src/components/hds/charts/donut/options.js @@ -1,3 +1,29 @@ +export default { + title: ' ', // Set title using @title on the component + resizable: true, + legend: { + // alignment: 'left', // = alignment w/i container, options: 'left', 'right', 'center' + position: 'left', // = position relative to chart, options: 'top', 'bottom', 'left', 'right' + truncation: { + type: 'none', + }, + }, + toolbar: { + enabled: false, // hide toolbar + }, + donut: { + alignment: 'center', // = alignment w/i container, options: 'center', 'left', 'right' + }, + pie: { + labels: { + enabled: true, + formatter: (data) => data.value, + }, + }, + height: '175px', +}; + +/* export default { title: 'Donut (centered)', resizable: true, @@ -15,3 +41,4 @@ export default { }, height: '400px', }; +*/ diff --git a/packages/components/src/styles/components/charts/donut.scss b/packages/components/src/styles/components/charts/donut.scss index fcd37c6c587..75fbc3e7e62 100644 --- a/packages/components/src/styles/components/charts/donut.scss +++ b/packages/components/src/styles/components/charts/donut.scss @@ -8,6 +8,16 @@ // .hds-charts-donut { - // add the component styles here - outline: 1px dotted red; + // outline: 1px dotted red; // for testing - see boundaries of chart container + + // increase stroke definition on slices (especially for resized/shrunken charts) + .slice { + stroke: #fff; + stroke-width: 1px; + } + + // The size of the title affects the rendered size of the donut chart + .title { + min-height: 1.3em; + } } diff --git a/showcase/app/routes/components/charts/donut.js b/showcase/app/routes/components/charts/donut.js deleted file mode 100644 index 7b43e15a69a..00000000000 --- a/showcase/app/routes/components/charts/donut.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: MPL-2.0 - */ - -import Route from '@ember/routing/route'; - -export default class PageComponentsChartsDonutRoute extends Route {} diff --git a/showcase/app/routes/page-components/charts/donut.js b/showcase/app/routes/page-components/charts/donut.js new file mode 100644 index 00000000000..87106380075 --- /dev/null +++ b/showcase/app/routes/page-components/charts/donut.js @@ -0,0 +1,42 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Route from '@ember/routing/route'; + +const SERVICE_HEALTH_DATA = [ + { group: 'Critical', value: 38 }, + { group: 'Warning', value: 34 }, + { group: 'Healthy', value: 18 }, +]; + +/* + Note: Currently, Donut chart does not natively support sub-groups or hierarchical (multi-level) data. + (Sometimes called a "Sunburst chart".) + + Cannot do: + { + group: 'Consul Dedicated', + value: [ + { group: "below v.1.4", value: 1 }, + { group: "above v1.14.0", value: 0 } + ] + }, +*/ +const CLUSTERS_DATA = [ + { group: 'Self-managed', value: 2 }, + { + group: 'Consul Dedicated', + value: 1, + }, +]; + +export default class PageComponentsChartsDonutRoute extends Route { + async model() { + return { + SERVICE_HEALTH_DATA, + CLUSTERS_DATA, + }; + } +} diff --git a/showcase/app/templates/page-components/charts/donut.hbs b/showcase/app/templates/page-components/charts/donut.hbs index a4aa6239c29..d3c01ee4eaa 100644 --- a/showcase/app/templates/page-components/charts/donut.hbs +++ b/showcase/app/templates/page-components/charts/donut.hbs @@ -10,5 +10,26 @@ Carbon Charts test
- + + + Clusters + + + + + +
+ Services + From clusters above v1.14.0 +
+ 5 + +
+
+ + + Service Instances + + +
\ No newline at end of file From b38a313b8013a64245e057036b805b5a230be9db Mon Sep 17 00:00:00 2001 From: Kristin Bradley Date: Fri, 8 Aug 2025 14:27:47 -0700 Subject: [PATCH 3/8] HDS-5289 Add colorMap option to Donut, pass in custom colors for services instances chart example --- packages/components/package.json | 1 - .../src/components/hds/charts/donut/data.js | 26 ---------------- .../src/components/hds/charts/donut/index.ts | 13 ++++---- .../components/hds/charts/donut/options.js | 20 ------------- packages/components/src/template-registry.ts | 30 ++++++++++++------- .../page-components/charts/donut.hbs | 6 +++- 6 files changed, 32 insertions(+), 64 deletions(-) delete mode 100644 packages/components/src/components/hds/charts/donut/data.js diff --git a/packages/components/package.json b/packages/components/package.json index e379e2071cf..2c637a71d73 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -200,7 +200,6 @@ "./components/hds/button-set/index.js": "./dist/_app_/components/hds/button-set/index.js", "./components/hds/button/index.js": "./dist/_app_/components/hds/button/index.js", "./components/hds/card/container.js": "./dist/_app_/components/hds/card/container.js", - "./components/hds/charts/donut/data.js": "./dist/_app_/components/hds/charts/donut/data.js", "./components/hds/charts/donut/index.js": "./dist/_app_/components/hds/charts/donut/index.js", "./components/hds/charts/donut/options.js": "./dist/_app_/components/hds/charts/donut/options.js", "./components/hds/code-block/copy-button.js": "./dist/_app_/components/hds/code-block/copy-button.js", diff --git a/packages/components/src/components/hds/charts/donut/data.js b/packages/components/src/components/hds/charts/donut/data.js deleted file mode 100644 index c5870de558a..00000000000 --- a/packages/components/src/components/hds/charts/donut/data.js +++ /dev/null @@ -1,26 +0,0 @@ -export default [ - { - group: '2V2N 9KYPM version 1', // group = label/category - value: 20000, - }, - { - group: 'L22I P66EP L22I P66EP L22I P66EP', - value: 65000, - }, - { - group: 'JQAI 2M4L1', - value: 75000, - }, - { - group: 'J9DZ F37AP', - value: 1200, - }, - { - group: 'YEL48 Q6XK YEL48', - value: 10000, - }, - { - group: 'Misc', - value: 25000, - }, -]; diff --git a/packages/components/src/components/hds/charts/donut/index.ts b/packages/components/src/components/hds/charts/donut/index.ts index 6b7da21603f..f3dc93eb09d 100644 --- a/packages/components/src/components/hds/charts/donut/index.ts +++ b/packages/components/src/components/hds/charts/donut/index.ts @@ -8,32 +8,33 @@ import { action } from '@ember/object'; import { DonutChart } from '@carbon/charts'; import options from './options.js'; -import data from './data.js'; import '@carbon/charts/styles.css'; - export interface HdsChartsDonutSignature { Args: { title?: string; - data?: Array<{ group: string; value: number }>; + data: Array<{ group: string; value: number }>; + colorMap?: { [key: string]: string }; // Optional custom colors for the chart segments/slices }; Blocks: { default: []; }; Element: HTMLDivElement; } -// More info on types and signatures: https://hashicorp.atlassian.net/wiki/spaces/HDS/pages/3245932580/Using+Typescript export default class HdsChartsDonut extends Component { chart: DonutChart | null = null; @action setupChart(element: HTMLDivElement): void { - const chartData = this.args.data || data; + const chartData = this.args.data; // Merge the dynamic title into the options const chartOptions = { ...options, - title: this.args.title || options.title, // Use the passed title or fallback to the default + title: this.args.title || options.title, + color: { + scale: this.args.colorMap, + }, }; this.chart = new DonutChart(element, { diff --git a/packages/components/src/components/hds/charts/donut/options.js b/packages/components/src/components/hds/charts/donut/options.js index c76d7c004b9..577159fd1cf 100644 --- a/packages/components/src/components/hds/charts/donut/options.js +++ b/packages/components/src/components/hds/charts/donut/options.js @@ -22,23 +22,3 @@ export default { }, height: '175px', }; - -/* -export default { - title: 'Donut (centered)', - resizable: true, - legend: { - position: 'right', - truncation: { - type: 'none', - }, - }, - donut: { - center: { - label: 'Browsers', - }, - alignment: 'center', - }, - height: '400px', -}; -*/ diff --git a/packages/components/src/template-registry.ts b/packages/components/src/template-registry.ts index 66b79a5e3d1..722aef2e674 100644 --- a/packages/components/src/template-registry.ts +++ b/packages/components/src/template-registry.ts @@ -22,22 +22,14 @@ import type HdsAdvancedTableExpandableTrGroupComponent from './components/hds/ad import type HdsAlertComponent from './components/hds/alert'; import type HdsAlertDescriptionComponent from './components/hds/alert/description'; import type HdsAlertTitleComponent from './components/hds/alert/title'; -import type HdsAppHeaderComponent from './components/hds/app-header'; -import type HdsAppHeaderHomeLinkComponent from './components/hds/app-header/home-link'; -import type HdsAppHeaderMenuButtonComponent from './components/hds/app-header/menu-button'; + import type HdsAppFooterComponent from './components/hds/app-footer'; import type HdsAppFooterCopyrightComponent from './components/hds/app-footer/copyright'; import type HdsAppFooterItemComponent from './components/hds/app-footer/item'; import type HdsAppFooterLegalLinksComponent from './components/hds/app-footer/legal-links'; import type HdsAppFooterLinkComponent from './components/hds/app-footer/link'; import type HdsAppFooterStatusLinkComponent from './components/hds/app-footer/status-link'; -import type HdsBadgeComponent from './components/hds/badge'; -import type HdsBadgeCountComponent from './components/hds/badge-count'; -import type HdsBreadcrumbComponent from './components/hds/breadcrumb/index.ts'; -import type HdsBreadcrumbItemComponent from './components/hds/breadcrumb/item'; -import type HdsBreadcrumbTruncationComponent from './components/hds/breadcrumb/truncation.ts'; -import type HdsButtonComponent from './components/hds/button'; -import type HdsButtonSetComponent from './components/hds/button-set'; + import type HdsAppFrameComponent from './components/hds/app-frame'; import type HdsAppFrameFooterComponent from './components/hds/app-frame/parts/footer'; import type HdsAppFrameHeaderComponent from './components/hds/app-frame/parts/header'; @@ -45,6 +37,10 @@ import type HdsAppFrameMainComponent from './components/hds/app-frame/parts/main import type HdsAppFrameModalsComponent from './components/hds/app-frame/parts/modals'; import type HdsAppFrameSidebarComponent from './components/hds/app-frame/parts/sidebar'; +import type HdsAppHeaderComponent from './components/hds/app-header'; +import type HdsAppHeaderHomeLinkComponent from './components/hds/app-header/home-link'; +import type HdsAppHeaderMenuButtonComponent from './components/hds/app-header/menu-button'; + import type HdsAppSideNavComponent from './components/hds/app-side-nav'; import type HdsAppSideNavToggleButtonComponent from './components/hds/app-side-nav/toggle-button'; import type HdsAppSideNavPortalComponent from './components/hds/app-side-nav/portal'; @@ -60,7 +56,18 @@ import type HdsApplicationStateBodyComponent from './components/hds/application- import type HdsApplicationStateFooterComponent from './components/hds/application-state/footer'; import type HdsApplicationStateHeaderComponent from './components/hds/application-state/header'; import type HdsApplicationStateMediaComponent from './components/hds/application-state/media'; + +import type HdsBadgeComponent from './components/hds/badge'; +import type HdsBadgeCountComponent from './components/hds/badge-count'; +import type HdsBreadcrumbComponent from './components/hds/breadcrumb/index.ts'; +import type HdsBreadcrumbItemComponent from './components/hds/breadcrumb/item'; +import type HdsBreadcrumbTruncationComponent from './components/hds/breadcrumb/truncation.ts'; +import type HdsButtonComponent from './components/hds/button'; +import type HdsButtonSetComponent from './components/hds/button-set'; import type HdsCardContainerComponent from './components/hds/card/container.ts'; + +import type HdsChartsDonut from './components/hds/charts/donut/index.ts'; + import type HdsCodeEditorComponent from './components/hds/code-editor/index.ts'; import type HdsCodeEditorDescriptionComponent from './components/hds/code-editor/description.ts'; import type HdsCodeEditorGenericComponent from './components/hds/code-editor/generic.ts'; @@ -433,6 +440,9 @@ export default interface HdsComponentsRegistry { 'Hds::Card::Container': typeof HdsCardContainerComponent; 'hds/card/container': typeof HdsCardContainerComponent; + // Charts + 'Hds::Charts::Donut': typeof HdsChartsDonut; + // Code Block 'Hds::CodeBlock': typeof HdsCodeBlockComponent; 'hds/code-block': typeof HdsCodeBlockComponent; diff --git a/showcase/app/templates/page-components/charts/donut.hbs b/showcase/app/templates/page-components/charts/donut.hbs index d3c01ee4eaa..fa8b5dfa109 100644 --- a/showcase/app/templates/page-components/charts/donut.hbs +++ b/showcase/app/templates/page-components/charts/donut.hbs @@ -29,7 +29,11 @@ Service Instances - + \ No newline at end of file From e0276f2199d01293680588e999ffc30d7f08b1f5 Mon Sep 17 00:00:00 2001 From: Kristin Bradley Date: Fri, 8 Aug 2025 14:31:53 -0700 Subject: [PATCH 4/8] HDS-5289 Remove level from Card examples --- showcase/app/templates/page-components/charts/donut.hbs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/showcase/app/templates/page-components/charts/donut.hbs b/showcase/app/templates/page-components/charts/donut.hbs index fa8b5dfa109..337f11727b4 100644 --- a/showcase/app/templates/page-components/charts/donut.hbs +++ b/showcase/app/templates/page-components/charts/donut.hbs @@ -11,12 +11,12 @@
- + Clusters - +
Services @@ -27,7 +27,7 @@ - + Service Instances Date: Mon, 11 Aug 2025 17:11:19 -0700 Subject: [PATCH 5/8] HDS-5289 Add Meter Chart components based on Carbon Charts Meter, consolidate Showcase page for chart components into one, add example meters --- packages/components/package.json | 2 + .../src/components/hds/charts/donut/index.ts | 3 +- .../src/components/hds/charts/meter/index.hbs | 6 ++ .../src/components/hds/charts/meter/index.ts | 57 +++++++++++++ .../components/hds/charts/meter/options.js | 12 +++ .../@hashicorp/design-system-components.scss | 2 +- .../{charts/donut.scss => charts.scss} | 0 packages/components/src/template-registry.ts | 2 + showcase/app/router.ts | 6 +- .../routes/page-components/charts/donut.js | 42 ---------- .../routes/page-components/charts/index.js | 82 +++++++++++++++++++ showcase/app/templates/index.hbs | 4 +- .../charts/{donut.hbs => index.hbs} | 26 ++++-- .../hds/charts/{donut.js => index.js} | 4 +- showcase/tests/acceptance/percy-test.js | 4 +- .../components/hds/charts/meter/index-test.js | 18 ++++ 16 files changed, 212 insertions(+), 58 deletions(-) create mode 100644 packages/components/src/components/hds/charts/meter/index.hbs create mode 100644 packages/components/src/components/hds/charts/meter/index.ts create mode 100644 packages/components/src/components/hds/charts/meter/options.js rename packages/components/src/styles/components/{charts/donut.scss => charts.scss} (100%) delete mode 100644 showcase/app/routes/page-components/charts/donut.js create mode 100644 showcase/app/routes/page-components/charts/index.js rename showcase/app/templates/page-components/charts/{donut.hbs => index.hbs} (60%) rename showcase/tests/acceptance/components/hds/charts/{donut.js => index.js} (73%) create mode 100644 showcase/tests/integration/components/hds/charts/meter/index-test.js diff --git a/packages/components/package.json b/packages/components/package.json index 2c637a71d73..96128368fd2 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -202,6 +202,8 @@ "./components/hds/card/container.js": "./dist/_app_/components/hds/card/container.js", "./components/hds/charts/donut/index.js": "./dist/_app_/components/hds/charts/donut/index.js", "./components/hds/charts/donut/options.js": "./dist/_app_/components/hds/charts/donut/options.js", + "./components/hds/charts/meter/index.js": "./dist/_app_/components/hds/charts/meter/index.js", + "./components/hds/charts/meter/options.js": "./dist/_app_/components/hds/charts/meter/options.js", "./components/hds/code-block/copy-button.js": "./dist/_app_/components/hds/code-block/copy-button.js", "./components/hds/code-block/description.js": "./dist/_app_/components/hds/code-block/description.js", "./components/hds/code-block/index.js": "./dist/_app_/components/hds/code-block/index.js", diff --git a/packages/components/src/components/hds/charts/donut/index.ts b/packages/components/src/components/hds/charts/donut/index.ts index f3dc93eb09d..93c164a53df 100644 --- a/packages/components/src/components/hds/charts/donut/index.ts +++ b/packages/components/src/components/hds/charts/donut/index.ts @@ -28,7 +28,7 @@ export default class HdsChartsDonut extends Component { setupChart(element: HTMLDivElement): void { const chartData = this.args.data; - // Merge the dynamic title into the options + // Merge the dynamic options into the default options const chartOptions = { ...options, title: this.args.title || options.title, @@ -37,6 +37,7 @@ export default class HdsChartsDonut extends Component { }, }; + // Create the DonutChart instance this.chart = new DonutChart(element, { data: chartData, options: chartOptions, diff --git a/packages/components/src/components/hds/charts/meter/index.hbs b/packages/components/src/components/hds/charts/meter/index.hbs new file mode 100644 index 00000000000..44bcde1d8bb --- /dev/null +++ b/packages/components/src/components/hds/charts/meter/index.hbs @@ -0,0 +1,6 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} + +
\ No newline at end of file diff --git a/packages/components/src/components/hds/charts/meter/index.ts b/packages/components/src/components/hds/charts/meter/index.ts new file mode 100644 index 00000000000..cfc0649daa7 --- /dev/null +++ b/packages/components/src/components/hds/charts/meter/index.ts @@ -0,0 +1,57 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Component from '@glimmer/component'; +import { action } from '@ember/object'; + +import { MeterChart } from '@carbon/charts'; +import options from './options.js'; +import '@carbon/charts/styles.css'; + +export interface HdsChartsMeterSignature { + Args: { + title?: string; + data: Array<{ group: string; value: number }>; + total?: number; // if not passed in it will be calculated from the data + }; + Blocks: { + default: []; + }; + Element: HTMLDivElement; +} + +export default class HdsChartsMeter extends Component { + chart: MeterChart | null = null; + + @action + setupChart(element: HTMLDivElement): void { + const chartData = this.args.data; + + // Dynamically calculate the total from the passed-in data + const chartTotal = chartData.reduce( + (sum, item): number => sum + item.value, + 0 + ); + + // Merge the dynamic options into the default options + const chartOptions = { + ...options, + title: this.args.title || options.title, + meter: { + ...options.meter, + proportional: { + ...options.meter.proportional, + total: this.args.total || chartTotal, + }, + }, + }; + + // Create the MeterChart instance + this.chart = new MeterChart(element, { + data: chartData, + options: chartOptions, + }); + } +} diff --git a/packages/components/src/components/hds/charts/meter/options.js b/packages/components/src/components/hds/charts/meter/options.js new file mode 100644 index 00000000000..80982860fe4 --- /dev/null +++ b/packages/components/src/components/hds/charts/meter/options.js @@ -0,0 +1,12 @@ +export default { + title: '', + height: '130px', + meter: { + proportional: { + unit: '', + }, + }, + toolbar: { + enabled: false, // hide toolbar + }, +}; diff --git a/packages/components/src/styles/@hashicorp/design-system-components.scss b/packages/components/src/styles/@hashicorp/design-system-components.scss index 9cc0969da89..f488e056cde 100644 --- a/packages/components/src/styles/@hashicorp/design-system-components.scss +++ b/packages/components/src/styles/@hashicorp/design-system-components.scss @@ -26,7 +26,7 @@ @use "../components/button"; @use "../components/button-set"; @use "../components/card"; -@use "../components/charts/donut"; +@use "../components/charts"; @use "../components/code-block"; @use "../components/code-editor"; @use "../components/copy"; diff --git a/packages/components/src/styles/components/charts/donut.scss b/packages/components/src/styles/components/charts.scss similarity index 100% rename from packages/components/src/styles/components/charts/donut.scss rename to packages/components/src/styles/components/charts.scss diff --git a/packages/components/src/template-registry.ts b/packages/components/src/template-registry.ts index 722aef2e674..a8c2bd54d8b 100644 --- a/packages/components/src/template-registry.ts +++ b/packages/components/src/template-registry.ts @@ -67,6 +67,7 @@ import type HdsButtonSetComponent from './components/hds/button-set'; import type HdsCardContainerComponent from './components/hds/card/container.ts'; import type HdsChartsDonut from './components/hds/charts/donut/index.ts'; +import type HdsChartsMeter from './components/hds/charts/meter/index.ts'; import type HdsCodeEditorComponent from './components/hds/code-editor/index.ts'; import type HdsCodeEditorDescriptionComponent from './components/hds/code-editor/description.ts'; @@ -442,6 +443,7 @@ export default interface HdsComponentsRegistry { // Charts 'Hds::Charts::Donut': typeof HdsChartsDonut; + 'Hds::Charts::Meter': typeof HdsChartsMeter; // Code Block 'Hds::CodeBlock': typeof HdsCodeBlockComponent; diff --git a/showcase/app/router.ts b/showcase/app/router.ts index 7ba562963e2..aa9b7b81a6a 100644 --- a/showcase/app/router.ts +++ b/showcase/app/router.ts @@ -46,9 +46,9 @@ Router.map(function (): void { this.route('button'); this.route('button-set'); this.route('card'); - this.route('charts', function (): void { - this.route('donut'); - }); + + this.route('charts', function (): void {}); + this.route('code-block'); this.route('code-editor'); this.route('dropdown'); diff --git a/showcase/app/routes/page-components/charts/donut.js b/showcase/app/routes/page-components/charts/donut.js deleted file mode 100644 index 87106380075..00000000000 --- a/showcase/app/routes/page-components/charts/donut.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: MPL-2.0 - */ - -import Route from '@ember/routing/route'; - -const SERVICE_HEALTH_DATA = [ - { group: 'Critical', value: 38 }, - { group: 'Warning', value: 34 }, - { group: 'Healthy', value: 18 }, -]; - -/* - Note: Currently, Donut chart does not natively support sub-groups or hierarchical (multi-level) data. - (Sometimes called a "Sunburst chart".) - - Cannot do: - { - group: 'Consul Dedicated', - value: [ - { group: "below v.1.4", value: 1 }, - { group: "above v1.14.0", value: 0 } - ] - }, -*/ -const CLUSTERS_DATA = [ - { group: 'Self-managed', value: 2 }, - { - group: 'Consul Dedicated', - value: 1, - }, -]; - -export default class PageComponentsChartsDonutRoute extends Route { - async model() { - return { - SERVICE_HEALTH_DATA, - CLUSTERS_DATA, - }; - } -} diff --git a/showcase/app/routes/page-components/charts/index.js b/showcase/app/routes/page-components/charts/index.js new file mode 100644 index 00000000000..2e08b4b2a44 --- /dev/null +++ b/showcase/app/routes/page-components/charts/index.js @@ -0,0 +1,82 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Route from '@ember/routing/route'; + +// Donut data + +const DONUT_SERVICE_HEALTH_DATA = [ + { group: 'Critical', value: 38 }, + { group: 'Warning', value: 34 }, + { group: 'Healthy', value: 18 }, +]; + +/* + Note: Currently, Donut chart does not natively support sub-groups or hierarchical (multi-level) data. + (Sometimes called a "Sunburst chart".) + + Cannot do: + { + group: 'Consul Dedicated', + value: [ + { group: "below v.1.4", value: 1 }, + { group: "above v1.14.0", value: 0 } + ] + }, +*/ +const DONUT_CLUSTERS_DATA = [ + { group: 'Self-managed', value: 2 }, + { + group: 'Consul Dedicated', + value: 1, + }, +]; + +// Meter data + +const METER_DATABASE_TRANSACTIONS_DATA = [ + { + group: 'Create', + value: 174, + }, + { + group: 'Update', + value: 4, + }, + { + group: 'Replace', + value: 13, + }, + { + group: 'Import', + value: 84, + }, + { + group: 'Delete', + value: 3, + }, +]; + +const METER_BILLABLE_RESOURCES_DATA = [ + { + group: 'Stack resources', + value: 1200, + }, + { + group: 'Workspace resources', + value: 24500, + }, +]; + +export default class PageComponentsChartsRoute extends Route { + async model() { + return { + DONUT_SERVICE_HEALTH_DATA, + DONUT_CLUSTERS_DATA, + METER_DATABASE_TRANSACTIONS_DATA, + METER_BILLABLE_RESOURCES_DATA, + }; + } +} diff --git a/showcase/app/templates/index.hbs b/showcase/app/templates/index.hbs index c0b60893282..f5990bf0579 100644 --- a/showcase/app/templates/index.hbs +++ b/showcase/app/templates/index.hbs @@ -44,8 +44,8 @@
  1. - - Charts / Donut + + Various chart components
diff --git a/showcase/app/templates/page-components/charts/donut.hbs b/showcase/app/templates/page-components/charts/index.hbs similarity index 60% rename from showcase/app/templates/page-components/charts/donut.hbs rename to showcase/app/templates/page-components/charts/index.hbs index 337f11727b4..95a4c831c0f 100644 --- a/showcase/app/templates/page-components/charts/donut.hbs +++ b/showcase/app/templates/page-components/charts/index.hbs @@ -3,17 +3,17 @@ SPDX-License-Identifier: MPL-2.0 }} -{{page-title "Charts::Donut Component"}} +{{page-title "Charts"}} -Charts::Donut +Charts -Carbon Charts test +Carbon Charts Donut
Clusters - + @@ -31,9 +31,25 @@ Service Instances + + Carbon Charts Meter + + + + + + + + + +
\ No newline at end of file diff --git a/showcase/tests/acceptance/components/hds/charts/donut.js b/showcase/tests/acceptance/components/hds/charts/index.js similarity index 73% rename from showcase/tests/acceptance/components/hds/charts/donut.js rename to showcase/tests/acceptance/components/hds/charts/index.js index 2b4bb04f129..ffdcfaac529 100644 --- a/showcase/tests/acceptance/components/hds/charts/donut.js +++ b/showcase/tests/acceptance/components/hds/charts/index.js @@ -8,10 +8,10 @@ import { visit } from '@ember/test-helpers'; import { setupApplicationTest } from 'showcase/tests/helpers'; import { a11yAudit } from 'ember-a11y-testing/test-support'; -module('Acceptance | components/charts/donut', function (hooks) { +module('Acceptance | components/charts', function (hooks) { setupApplicationTest(hooks); - test('Components/charts/donut page passes automated a11y checks', async function (assert) { + test('Components/charts page passes automated a11y checks', async function (assert) { await visit('/components/charts/donut'); await a11yAudit(); diff --git a/showcase/tests/acceptance/percy-test.js b/showcase/tests/acceptance/percy-test.js index 567e18bc972..cf2bb238c5b 100644 --- a/showcase/tests/acceptance/percy-test.js +++ b/showcase/tests/acceptance/percy-test.js @@ -84,8 +84,8 @@ module('Acceptance | Percy test', function (hooks) { await visit('/components/card'); await percySnapshot('Card'); - await visit('/components/charts-donut'); - await percySnapshot('Charts/donut'); + await visit('/components/charts'); + await percySnapshot('Charts'); await visit('/components/code-block'); await percySnapshot('CodeBlock'); diff --git a/showcase/tests/integration/components/hds/charts/meter/index-test.js b/showcase/tests/integration/components/hds/charts/meter/index-test.js new file mode 100644 index 00000000000..af714074ecd --- /dev/null +++ b/showcase/tests/integration/components/hds/charts/meter/index-test.js @@ -0,0 +1,18 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'showcase/tests/helpers'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | hds/charts/meter/index', function (hooks) { + setupRenderingTest(hooks); + + test('it should render the component with a CSS class that matches the component name', async function (assert) { + await render(hbs``); + assert.dom('#test-charts-meter').hasClass('hds-charts-meter'); + }); +}); From 9079beeeeeb6dad40395525587ec2dc610bb1a72 Mon Sep 17 00:00:00 2001 From: Kristin Bradley Date: Tue, 12 Aug 2025 16:23:27 -0700 Subject: [PATCH 6/8] HDS-5289 Add simple bar chart component with Showcase example --- packages/components/package.json | 2 + .../src/components/hds/charts/bar/index.hbs | 6 +++ .../src/components/hds/charts/bar/index.ts | 43 +++++++++++++++ .../src/components/hds/charts/bar/options.js | 26 +++++++++ .../src/styles/components/charts.scss | 12 ++++- packages/components/src/template-registry.ts | 2 + .../routes/page-components/charts/index.js | 54 +++++++++++++++++++ .../page-components/charts/index.hbs | 6 +++ .../components/hds/charts/bar/index-test.js | 18 +++++++ 9 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 packages/components/src/components/hds/charts/bar/index.hbs create mode 100644 packages/components/src/components/hds/charts/bar/index.ts create mode 100644 packages/components/src/components/hds/charts/bar/options.js create mode 100644 showcase/tests/integration/components/hds/charts/bar/index-test.js diff --git a/packages/components/package.json b/packages/components/package.json index 96128368fd2..025abe76106 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -200,6 +200,8 @@ "./components/hds/button-set/index.js": "./dist/_app_/components/hds/button-set/index.js", "./components/hds/button/index.js": "./dist/_app_/components/hds/button/index.js", "./components/hds/card/container.js": "./dist/_app_/components/hds/card/container.js", + "./components/hds/charts/bar/index.js": "./dist/_app_/components/hds/charts/bar/index.js", + "./components/hds/charts/bar/options.js": "./dist/_app_/components/hds/charts/bar/options.js", "./components/hds/charts/donut/index.js": "./dist/_app_/components/hds/charts/donut/index.js", "./components/hds/charts/donut/options.js": "./dist/_app_/components/hds/charts/donut/options.js", "./components/hds/charts/meter/index.js": "./dist/_app_/components/hds/charts/meter/index.js", diff --git a/packages/components/src/components/hds/charts/bar/index.hbs b/packages/components/src/components/hds/charts/bar/index.hbs new file mode 100644 index 00000000000..5b6537ea286 --- /dev/null +++ b/packages/components/src/components/hds/charts/bar/index.hbs @@ -0,0 +1,6 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} + +
\ No newline at end of file diff --git a/packages/components/src/components/hds/charts/bar/index.ts b/packages/components/src/components/hds/charts/bar/index.ts new file mode 100644 index 00000000000..f315b632ff2 --- /dev/null +++ b/packages/components/src/components/hds/charts/bar/index.ts @@ -0,0 +1,43 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import Component from '@glimmer/component'; +import { action } from '@ember/object'; + +import { SimpleBarChart } from '@carbon/charts'; +import options from './options.js'; +import '@carbon/charts/styles.css'; + +export interface HdsChartsBarSignature { + Args: { + title?: string; + data: Array<{ group: string; date: string; value: number }>; + }; + Blocks: { + default: []; + }; + Element: HTMLDivElement; +} + +export default class HdsChartsBar extends Component { + chart: SimpleBarChart | null = null; + + @action + setupChart(element: HTMLDivElement): void { + const chartData = this.args.data; + + // Merge the dynamic options into the default options + const chartOptions = { + ...options, + title: this.args.title || options.title, + }; + + // Create the SimpleBarChart instance + this.chart = new SimpleBarChart(element, { + data: chartData, + options: chartOptions, + }); + } +} diff --git a/packages/components/src/components/hds/charts/bar/options.js b/packages/components/src/components/hds/charts/bar/options.js new file mode 100644 index 00000000000..5ad394ee481 --- /dev/null +++ b/packages/components/src/components/hds/charts/bar/options.js @@ -0,0 +1,26 @@ +import { ScaleTypes } from '@carbon/charts'; + +export default { + title: '', + toolbar: { + enabled: false, // hide toolbar + }, + axes: { + left: { + mapsTo: 'value', + }, + bottom: { + mapsTo: 'date', + scaleType: ScaleTypes.LABELS, + }, + }, + grid: { + x: { + numberOfTicks: 0, + }, + }, + height: '400px', + legend: { + enabled: false, // hide legend (for single color bar chart) + }, +}; diff --git a/packages/components/src/styles/components/charts.scss b/packages/components/src/styles/components/charts.scss index 75fbc3e7e62..5d1ac382934 100644 --- a/packages/components/src/styles/components/charts.scss +++ b/packages/components/src/styles/components/charts.scss @@ -4,9 +4,11 @@ */ // -// CHARTS > DONUT +// CHARTS // +// > DONUT + .hds-charts-donut { // outline: 1px dotted red; // for testing - see boundaries of chart container @@ -21,3 +23,11 @@ min-height: 1.3em; } } + +// > BAR + +.hds-charts-bar { + .graph-frame { + overflow: hidden; // cut off bottom line which overflows container + } +} diff --git a/packages/components/src/template-registry.ts b/packages/components/src/template-registry.ts index a8c2bd54d8b..87b75e8f818 100644 --- a/packages/components/src/template-registry.ts +++ b/packages/components/src/template-registry.ts @@ -68,6 +68,7 @@ import type HdsCardContainerComponent from './components/hds/card/container.ts'; import type HdsChartsDonut from './components/hds/charts/donut/index.ts'; import type HdsChartsMeter from './components/hds/charts/meter/index.ts'; +import type HdsChartsBar from './components/hds/charts/bar/index.ts'; import type HdsCodeEditorComponent from './components/hds/code-editor/index.ts'; import type HdsCodeEditorDescriptionComponent from './components/hds/code-editor/description.ts'; @@ -444,6 +445,7 @@ export default interface HdsComponentsRegistry { // Charts 'Hds::Charts::Donut': typeof HdsChartsDonut; 'Hds::Charts::Meter': typeof HdsChartsMeter; + 'Hds::Charts::Bar': typeof HdsChartsBar; // Code Block 'Hds::CodeBlock': typeof HdsCodeBlockComponent; diff --git a/showcase/app/routes/page-components/charts/index.js b/showcase/app/routes/page-components/charts/index.js index 2e08b4b2a44..33510fdef6d 100644 --- a/showcase/app/routes/page-components/charts/index.js +++ b/showcase/app/routes/page-components/charts/index.js @@ -70,6 +70,59 @@ const METER_BILLABLE_RESOURCES_DATA = [ }, ]; +// Bar data + +const BAR_MANAGED_RESOURCES_DATA = [ + { + date: '2025-01', + value: 9000, + }, + { + date: '2025-02', + value: 12000, + }, + { + date: '2025-03', + value: 10000, + }, + { + date: '2025-04', + value: 13000, + }, + { + date: '2025-05', + value: 14000, + }, + { + date: '2025-06', + value: 15000, + }, + { + date: '2025-07', + value: 15000, + }, + { + date: '2025-08', + value: 18000, + }, + { + date: '2025-09', + value: 21000, + }, + { + date: '2025-10', + value: 22000, + }, + { + date: '2025-11', + value: 24000, + }, + { + date: '2025-12', + value: 27000, + }, +]; + export default class PageComponentsChartsRoute extends Route { async model() { return { @@ -77,6 +130,7 @@ export default class PageComponentsChartsRoute extends Route { DONUT_CLUSTERS_DATA, METER_DATABASE_TRANSACTIONS_DATA, METER_BILLABLE_RESOURCES_DATA, + BAR_MANAGED_RESOURCES_DATA, }; } } diff --git a/showcase/app/templates/page-components/charts/index.hbs b/showcase/app/templates/page-components/charts/index.hbs index 95a4c831c0f..b2cefa12a4e 100644 --- a/showcase/app/templates/page-components/charts/index.hbs +++ b/showcase/app/templates/page-components/charts/index.hbs @@ -52,4 +52,10 @@ />
+ + Carbon Charts Bar + + + +
\ No newline at end of file diff --git a/showcase/tests/integration/components/hds/charts/bar/index-test.js b/showcase/tests/integration/components/hds/charts/bar/index-test.js new file mode 100644 index 00000000000..84d85848782 --- /dev/null +++ b/showcase/tests/integration/components/hds/charts/bar/index-test.js @@ -0,0 +1,18 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'showcase/tests/helpers'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | hds/charts/bar/index', function (hooks) { + setupRenderingTest(hooks); + + test('it should render the component with a CSS class that matches the component name', async function (assert) { + await render(hbs``); + assert.dom('#test-charts-bar').hasClass('hds-charts-bar'); + }); +}); From 373c17331777038cbcb43915d4d9b689f7e5271e Mon Sep 17 00:00:00 2001 From: Kristin Bradley Date: Wed, 13 Aug 2025 12:02:19 -0700 Subject: [PATCH 7/8] HDS-5289 Add title to donut chart example --- packages/components/src/components/hds/charts/donut/options.js | 2 +- showcase/app/templates/page-components/charts/index.hbs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/components/src/components/hds/charts/donut/options.js b/packages/components/src/components/hds/charts/donut/options.js index 577159fd1cf..6d4e5e630a5 100644 --- a/packages/components/src/components/hds/charts/donut/options.js +++ b/packages/components/src/components/hds/charts/donut/options.js @@ -1,5 +1,5 @@ export default { - title: ' ', // Set title using @title on the component + title: '', // Set title using @title on the component resizable: true, legend: { // alignment: 'left', // = alignment w/i container, options: 'left', 'right', 'center' diff --git a/showcase/app/templates/page-components/charts/index.hbs b/showcase/app/templates/page-components/charts/index.hbs index b2cefa12a4e..ef9b3449b54 100644 --- a/showcase/app/templates/page-components/charts/index.hbs +++ b/showcase/app/templates/page-components/charts/index.hbs @@ -13,7 +13,7 @@ Clusters - + From c624dd815c07a368333cf95aa249609163224df3 Mon Sep 17 00:00:00 2001 From: Kristin Bradley Date: Wed, 13 Aug 2025 14:11:25 -0700 Subject: [PATCH 8/8] HDS-5289 Fix failing tests --- .../integration/components/hds/charts/bar/index-test.js | 9 ++++++++- .../components/hds/charts/donut/index-test.js | 9 ++++++++- .../components/hds/charts/meter/index-test.js | 9 ++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/showcase/tests/integration/components/hds/charts/bar/index-test.js b/showcase/tests/integration/components/hds/charts/bar/index-test.js index 84d85848782..8dfd3ce9289 100644 --- a/showcase/tests/integration/components/hds/charts/bar/index-test.js +++ b/showcase/tests/integration/components/hds/charts/bar/index-test.js @@ -12,7 +12,14 @@ module('Integration | Component | hds/charts/bar/index', function (hooks) { setupRenderingTest(hooks); test('it should render the component with a CSS class that matches the component name', async function (assert) { - await render(hbs``); + this.data = [ + { date: '2025-01', value: 1000 }, + { date: '2025-02', value: 1500 }, + ]; + + await render( + hbs``, + ); assert.dom('#test-charts-bar').hasClass('hds-charts-bar'); }); }); diff --git a/showcase/tests/integration/components/hds/charts/donut/index-test.js b/showcase/tests/integration/components/hds/charts/donut/index-test.js index 45118ae5f59..5b6f50dc91a 100644 --- a/showcase/tests/integration/components/hds/charts/donut/index-test.js +++ b/showcase/tests/integration/components/hds/charts/donut/index-test.js @@ -12,7 +12,14 @@ module('Integration | Component | hds/charts/donut/index', function (hooks) { setupRenderingTest(hooks); test('it should render the component with a CSS class that matches the component name', async function (assert) { - await render(hbs``); + this.data = [ + { group: 'group 1', value: 2 }, + { group: 'group 2', value: 4 }, + ]; + + await render( + hbs``, + ); assert.dom('#test-charts-donut').hasClass('hds-charts-donut'); }); }); diff --git a/showcase/tests/integration/components/hds/charts/meter/index-test.js b/showcase/tests/integration/components/hds/charts/meter/index-test.js index af714074ecd..91d6db1c070 100644 --- a/showcase/tests/integration/components/hds/charts/meter/index-test.js +++ b/showcase/tests/integration/components/hds/charts/meter/index-test.js @@ -12,7 +12,14 @@ module('Integration | Component | hds/charts/meter/index', function (hooks) { setupRenderingTest(hooks); test('it should render the component with a CSS class that matches the component name', async function (assert) { - await render(hbs``); + this.data = [ + { group: 'Test group 1', value: 30 }, + { group: 'Test group 2', value: 70 }, + ]; + + await render( + hbs``, + ); assert.dom('#test-charts-meter').hasClass('hds-charts-meter'); }); });