-
Notifications
You must be signed in to change notification settings - Fork 4
CS-282: Create FunnelChart Component #419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
810fd3f
chartJs funnel dependency
miguelopezv 03cb80e
FunnelChart component
miguelopezv ccab1c5
FunnelChart tests
miguelopezv 374d939
FunnelChart storybook file
miguelopezv 099672d
export component
miguelopezv 9f465eb
update label styling
miguelopezv 786ff0f
add changeset file
miguelopezv 5b8e83b
Merge branch 'main' into CS-282
miguelopezv aedc6d7
update test coverage
miguelopezv 3583041
coderabbit proposed fixes
miguelopezv d15e7b6
Merge remote-tracking branch 'refs/remotes/origin/CS-282' into CS-282
miguelopezv c8669a8
Component improvements
miguelopezv fa2c883
test and stories update
miguelopezv 618218f
update legendPosition prop
miguelopezv 64d3b79
update export
miguelopezv b8ada82
update mergedData method
miguelopezv 30d610d
percentageDecimalPlaces implementation
miguelopezv ab6b61f
props fix
miguelopezv 718ecff
Merge branch 'main' into CS-282
miguelopezv be32e0d
restore types
miguelopezv f6bc3f3
Merge remote-tracking branch 'refs/remotes/origin/CS-282' into CS-282
miguelopezv 5573182
PR AI comment fix
miguelopezv File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@embeddable.com/remarkable-ui': minor | ||
| --- | ||
|
|
||
| Add FunnelChart component |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import type { Meta, StoryObj } from '@storybook/react-webpack5'; | ||
|
|
||
| import { FunnelChart } from './FunnelChart'; | ||
| import { funnelDataMock } from './funnel.mock'; | ||
| import { decoratorsResizeCard, decoratorsSquare } from '../../../storybook.constants'; | ||
|
|
||
| const meta = { | ||
| title: 'Charts/FunnelChart', | ||
| component: FunnelChart, | ||
| args: { | ||
| data: funnelDataMock, | ||
| showValueLabels: true, | ||
| showPercentage: false, | ||
| percentageDecimalPlaces: 1, | ||
| }, | ||
| } satisfies Meta<typeof FunnelChart>; | ||
|
|
||
| export default meta; | ||
|
|
||
| type Story = StoryObj<typeof meta>; | ||
|
|
||
| export const Default: Story = { | ||
| decorators: decoratorsSquare, | ||
| }; | ||
|
|
||
| export const Resize: Story = { | ||
| decorators: decoratorsResizeCard, | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| import { render, screen } from '@testing-library/react'; | ||
| import userEvent from '@testing-library/user-event'; | ||
| import { describe, expect, it, vi } from 'vitest'; | ||
| import { FunnelChart } from './FunnelChart'; | ||
| import { funnelDataMock } from './funnel.mock'; | ||
|
|
||
| vi.mock('react-chartjs-2', async () => { | ||
| const { forwardRef } = await import('react'); | ||
| return { | ||
| Chart: forwardRef( | ||
| ( | ||
| { onClick }: { onClick?: React.MouseEventHandler<HTMLCanvasElement> }, | ||
| ref: React.Ref<HTMLCanvasElement>, | ||
| ) => <canvas data-testid="funnel-chart" onClick={onClick} ref={ref} />, | ||
| ), | ||
| getElementAtEvent: vi.fn(() => []), | ||
| getElementsAtEvent: vi.fn(() => []), | ||
| getDatasetAtEvent: vi.fn(() => []), | ||
| }; | ||
| }); | ||
|
|
||
| const MOCK_DATA = funnelDataMock; | ||
|
|
||
| describe('FunnelChart', () => { | ||
| describe('rendering', () => { | ||
| it('renders the chart canvas', () => { | ||
| render(<FunnelChart data={MOCK_DATA} />); | ||
|
|
||
| expect(screen.getByTestId('funnel-chart')).toBeInTheDocument(); | ||
| }); | ||
| }); | ||
|
|
||
| describe('onClick', () => { | ||
| it('calls onClick with the event and chartRef', async () => { | ||
| const user = userEvent.setup(); | ||
| const handleClick = vi.fn(); | ||
|
|
||
| render(<FunnelChart data={MOCK_DATA} onClick={handleClick} />); | ||
|
|
||
| await user.click(screen.getByTestId('funnel-chart')); | ||
|
|
||
| expect(handleClick).toHaveBeenCalledWith({ | ||
| event: expect.objectContaining({ type: 'click' }), | ||
| elementAtEvent: [], | ||
| elementsAtEvent: [], | ||
| datasetAtEvent: [], | ||
| }); | ||
| }); | ||
|
|
||
| it('does not throw when onClick is not provided', async () => { | ||
| const user = userEvent.setup(); | ||
|
|
||
| render(<FunnelChart data={MOCK_DATA} />); | ||
|
|
||
| await user.click(screen.getByTestId('funnel-chart')); | ||
| }); | ||
| }); | ||
| }); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| import { FC, useRef } from 'react'; | ||
| import { Chart } from 'react-chartjs-2'; | ||
| import { buildChartjsOnClick } from '../chartjs.utils'; | ||
| import { Chart as ChartJS, CategoryScale, LinearScale, Tooltip, Legend } from 'chart.js'; | ||
| import { FunnelController, TrapezoidElement } from 'chartjs-chart-funnel'; | ||
| import { getFunnelChartData, getFunnelChartOptions } from './funnel.utils'; | ||
| import { BaseFunnelChartProps } from './funnel.types'; | ||
| import styles from '../charts.module.css'; | ||
| import { mergician } from 'mergician'; | ||
| import ChartDataLabels from 'chartjs-plugin-datalabels'; | ||
|
|
||
| ChartJS.register( | ||
| FunnelController, | ||
| TrapezoidElement, | ||
| CategoryScale, | ||
| LinearScale, | ||
| Tooltip, | ||
| Legend, | ||
| ChartDataLabels, | ||
| ); | ||
|
|
||
| export type FunnelChartProps = BaseFunnelChartProps; | ||
|
|
||
| export const FunnelChart: FC<FunnelChartProps> = ({ | ||
| data, | ||
| options = {}, | ||
| onClick, | ||
| showLegend = true, | ||
| showTooltips = true, | ||
| showValueLabels = true, | ||
| showPercentage = false, | ||
| percentageDecimalPlaces = 1, | ||
| }) => { | ||
| const chartRef = useRef(null); | ||
| const funnelOptions = mergician( | ||
| getFunnelChartOptions({ | ||
| showLegend, | ||
| showTooltips, | ||
| showValueLabels, | ||
| showPercentage, | ||
| percentageDecimalPlaces, | ||
| }), | ||
| options, | ||
| ); | ||
|
|
||
| return ( | ||
| <div className={styles.chartContainer}> | ||
| <Chart | ||
| ref={chartRef} | ||
| type="funnel" | ||
| data={getFunnelChartData(data)} | ||
| options={funnelOptions} | ||
| onClick={buildChartjsOnClick(chartRef, onClick)} | ||
| /> | ||
| </div> | ||
| ); | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| export const funnelDataMock = { | ||
| labels: ['Near Misses', 'Injury/Illness', 'Recordable', 'DART'], | ||
| datasets: [ | ||
| { | ||
| data: [33, 30, 14, 5], | ||
| }, | ||
| ], | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import 'chartjs-chart-funnel'; | ||
| import { ChartData, ChartOptions } from 'chart.js'; | ||
| import { ChartClickArgs } from '../charts.types'; | ||
|
|
||
| export type FunnelChartConfigurationProps = { | ||
| showLegend?: boolean; | ||
| showTooltips?: boolean; | ||
| showValueLabels?: boolean; | ||
| showPercentage?: boolean; | ||
| percentageDecimalPlaces?: number; | ||
| }; | ||
|
|
||
| export type BaseFunnelChartProps = { | ||
| data: ChartData<'funnel'>; | ||
| options?: Partial<ChartOptions<'funnel'>>; | ||
| onClick?: (args: ChartClickArgs) => void; | ||
| } & FunnelChartConfigurationProps; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.