Skip to content

Commit

Permalink
Charts: Adding pie charts (#40581)
Browse files Browse the repository at this point in the history
* Charts - Adding basic pie chart

* Charts - Updating charts and adding a tooltip hook

* Charts - Adding doughts to pies

* Charts - Fixing dependency

* changelog

* Charts - Adding chart TS interface

* Charts - Adding shared chart TS interface

* Charts - Cleanup

* Charts - Cleanup 2

* Charts - updating tooltip prop and simplifying event handlers
  • Loading branch information
grzegorz-cp authored Dec 16, 2024
1 parent 09c215f commit 5e270fb
Show file tree
Hide file tree
Showing 18 changed files with 880 additions and 118 deletions.
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions projects/js-packages/charts/changelog/add-charts-pie-chart
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: added

Adding new chart type - pie chart.
1 change: 1 addition & 0 deletions projects/js-packages/charts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"dependencies": {
"@react-spring/web": "9.7.3",
"@visx/responsive": "3.12.0",
"@visx/axis": "^3.12.0",
"@visx/group": "^3.12.0",
"@visx/scale": "^3.12.0",
Expand Down
70 changes: 23 additions & 47 deletions projects/js-packages/charts/src/components/bar-chart/bar-chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,25 @@ import { scaleBand, scaleLinear } from '@visx/scale';
import { Bar } from '@visx/shape';
import { useTooltip } from '@visx/tooltip';
import clsx from 'clsx';
import { FC, useCallback } from 'react';
import { FC, useCallback, type MouseEvent } from 'react';
import { useChartTheme } from '../../providers/theme';
import { BaseTooltip } from '../tooltip';
import styles from './bar-chart.module.scss';
import type { DataPoint } from '../shared/types';
import type { BaseChartProps, DataPoint } from '../shared/types';

type BarChartProps = {
interface BarChartProps extends BaseChartProps {
/**
* Array of data points to display in the chart
*/
data: DataPoint[];
/**
* Width of the chart in pixels
*/
width: number;
/**
* Height of the chart in pixels
*/
height: number;
/**
* Chart margins
*/
margin?: {
top?: number;
right?: number;
bottom?: number;
left?: number;
};
/**
* Whether to show tooltips on hover
*/
showTooltips?: boolean;
};
}

const BarChart: FC< BarChartProps > = ( {
data,
width,
height,
margin = { top: 20, right: 20, bottom: 40, left: 40 },
showTooltips = false,
withTooltips = false,
} ) => {
const theme = useChartTheme();
const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, hideTooltip, showTooltip } =
Expand All @@ -66,7 +45,7 @@ const BarChart: FC< BarChartProps > = ( {
} );

const handleMouseMove = useCallback(
( event: React.MouseEvent, datum: DataPoint ) => {
( event: MouseEvent< SVGRectElement >, datum: DataPoint ) => {
const coords = localPoint( event );
if ( ! coords ) return;

Expand All @@ -83,35 +62,32 @@ const BarChart: FC< BarChartProps > = ( {
hideTooltip();
}, [ hideTooltip ] );

const handleBarMouseMove = useCallback(
( d: DataPoint ) => ( event: React.MouseEvent< SVGRectElement > ) => {
handleMouseMove( event, d );
},
[ handleMouseMove ]
);

return (
<div className={ clsx( 'bar-chart', styles[ 'bar-chart' ] ) }>
<svg width={ width } height={ height }>
<Group left={ margins.left } top={ margins.top }>
{ data.map( d => (
<Bar
key={ `bar-${ d.label }` }
x={ xScale( d.label ) }
y={ yScale( d.value ) }
width={ xScale.bandwidth() }
height={ yMax - ( yScale( d.value ) ?? 0 ) }
fill={ theme.colors[ 0 ] }
onMouseMove={ handleBarMouseMove( d ) }
onMouseLeave={ handleMouseLeave }
/>
) ) }
{ data.map( d => {
const handleBarMouseMove = event => handleMouseMove( event, d );

return (
<Bar
key={ `bar-${ d.label }` }
x={ xScale( d.label ) }
y={ yScale( d.value ) }
width={ xScale.bandwidth() }
height={ yMax - ( yScale( d.value ) ?? 0 ) }
fill={ theme.colors[ 0 ] }
onMouseMove={ withTooltips ? handleBarMouseMove : undefined }
onMouseLeave={ withTooltips ? handleMouseLeave : undefined }
/>
);
} ) }
<AxisLeft scale={ yScale } />
<AxisBottom scale={ xScale } top={ yMax } />
</Group>
</svg>

{ showTooltips && tooltipOpen && tooltipData && (
{ withTooltips && tooltipOpen && tooltipData && (
<BaseTooltip
data={ {
label: tooltipData.label,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
import BarChart from '../index';
import data from './sample-data';
import type { Meta } from '@storybook/react';

const data = [
{ label: 'Jan', value: 12 },
{ label: 'Feb', value: 18 },
{ label: 'Mar', value: 29 },
{ label: 'Apr', value: 33 },
{ label: 'May', value: 45 },
{ label: 'Jun', value: 52 },
];

export default {
title: 'JS Packages/Charts/Types/Bar Chart',
component: BarChart,
Expand All @@ -32,14 +24,14 @@ Default.args = {
width: 500,
height: 300,
margin: { top: 20, right: 20, bottom: 40, left: 40 },
data,
showTooltips: false,
withTooltips: false,
data: data[ 0 ].data,
};

export const WithTooltips = Template.bind( {} );
WithTooltips.args = {
...Default.args,
showTooltips: true,
withTooltips: true,
};

WithTooltips.parameters = {
Expand Down
Loading

0 comments on commit 5e270fb

Please sign in to comment.