Some checks failed
No response / noResponse (push) Has been cancelled
CI / Continuous releases (push) Has been cancelled
CI / test-dev (macos-latest) (push) Has been cancelled
CI / test-dev (ubuntu-latest) (push) Has been cancelled
CI / test-dev (windows-latest) (push) Has been cancelled
Maintenance / main (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
196 lines
4.9 KiB
JavaScript
196 lines
4.9 KiB
JavaScript
import * as React from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import { PieChart } from '@mui/x-charts/PieChart';
|
|
import { useDrawingArea } from '@mui/x-charts/hooks';
|
|
import { styled } from '@mui/material/styles';
|
|
import Typography from '@mui/material/Typography';
|
|
import Card from '@mui/material/Card';
|
|
import CardContent from '@mui/material/CardContent';
|
|
import Box from '@mui/material/Box';
|
|
import Stack from '@mui/material/Stack';
|
|
import LinearProgress, { linearProgressClasses } from '@mui/material/LinearProgress';
|
|
|
|
import {
|
|
IndiaFlag,
|
|
UsaFlag,
|
|
BrazilFlag,
|
|
GlobeFlag,
|
|
} from '../internals/components/CustomIcons';
|
|
|
|
const data = [
|
|
{ label: 'India', value: 50000 },
|
|
{ label: 'USA', value: 35000 },
|
|
{ label: 'Brazil', value: 10000 },
|
|
{ label: 'Other', value: 5000 },
|
|
];
|
|
|
|
const countries = [
|
|
{
|
|
name: 'India',
|
|
value: 50,
|
|
flag: <IndiaFlag />,
|
|
color: 'hsl(220, 25%, 65%)',
|
|
},
|
|
{
|
|
name: 'USA',
|
|
value: 35,
|
|
flag: <UsaFlag />,
|
|
color: 'hsl(220, 25%, 45%)',
|
|
},
|
|
{
|
|
name: 'Brazil',
|
|
value: 10,
|
|
flag: <BrazilFlag />,
|
|
color: 'hsl(220, 25%, 30%)',
|
|
},
|
|
{
|
|
name: 'Other',
|
|
value: 5,
|
|
flag: <GlobeFlag />,
|
|
color: 'hsl(220, 25%, 20%)',
|
|
},
|
|
];
|
|
|
|
const StyledText = styled('text', {
|
|
shouldForwardProp: (prop) => prop !== 'variant',
|
|
})(({ theme }) => ({
|
|
textAnchor: 'middle',
|
|
dominantBaseline: 'central',
|
|
fill: (theme.vars || theme).palette.text.secondary,
|
|
variants: [
|
|
{
|
|
props: {
|
|
variant: 'primary',
|
|
},
|
|
style: {
|
|
fontSize: theme.typography.h5.fontSize,
|
|
},
|
|
},
|
|
{
|
|
props: ({ variant }) => variant !== 'primary',
|
|
style: {
|
|
fontSize: theme.typography.body2.fontSize,
|
|
},
|
|
},
|
|
{
|
|
props: {
|
|
variant: 'primary',
|
|
},
|
|
style: {
|
|
fontWeight: theme.typography.h5.fontWeight,
|
|
},
|
|
},
|
|
{
|
|
props: ({ variant }) => variant !== 'primary',
|
|
style: {
|
|
fontWeight: theme.typography.body2.fontWeight,
|
|
},
|
|
},
|
|
],
|
|
}));
|
|
|
|
function PieCenterLabel({ primaryText, secondaryText }) {
|
|
const { width, height, left, top } = useDrawingArea();
|
|
const primaryY = top + height / 2 - 10;
|
|
const secondaryY = primaryY + 24;
|
|
|
|
return (
|
|
<React.Fragment>
|
|
<StyledText variant="primary" x={left + width / 2} y={primaryY}>
|
|
{primaryText}
|
|
</StyledText>
|
|
<StyledText variant="secondary" x={left + width / 2} y={secondaryY}>
|
|
{secondaryText}
|
|
</StyledText>
|
|
</React.Fragment>
|
|
);
|
|
}
|
|
|
|
PieCenterLabel.propTypes = {
|
|
primaryText: PropTypes.string.isRequired,
|
|
secondaryText: PropTypes.string.isRequired,
|
|
};
|
|
|
|
const colors = [
|
|
'hsl(220, 20%, 65%)',
|
|
'hsl(220, 20%, 42%)',
|
|
'hsl(220, 20%, 35%)',
|
|
'hsl(220, 20%, 25%)',
|
|
];
|
|
|
|
export default function ChartUserByCountry() {
|
|
return (
|
|
<Card
|
|
variant="outlined"
|
|
sx={{ display: 'flex', flexDirection: 'column', gap: '8px', flexGrow: 1 }}
|
|
>
|
|
<CardContent>
|
|
<Typography component="h2" variant="subtitle2">
|
|
Users by country
|
|
</Typography>
|
|
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
|
<PieChart
|
|
colors={colors}
|
|
margin={{
|
|
left: 80,
|
|
right: 80,
|
|
top: 80,
|
|
bottom: 80,
|
|
}}
|
|
series={[
|
|
{
|
|
data,
|
|
innerRadius: 75,
|
|
outerRadius: 100,
|
|
paddingAngle: 0,
|
|
highlightScope: { fade: 'global', highlight: 'item' },
|
|
},
|
|
]}
|
|
height={260}
|
|
width={260}
|
|
hideLegend
|
|
>
|
|
<PieCenterLabel primaryText="98.5K" secondaryText="Total" />
|
|
</PieChart>
|
|
</Box>
|
|
{countries.map((country, index) => (
|
|
<Stack
|
|
key={index}
|
|
direction="row"
|
|
sx={{ alignItems: 'center', gap: 2, pb: 2 }}
|
|
>
|
|
{country.flag}
|
|
<Stack sx={{ gap: 1, flexGrow: 1 }}>
|
|
<Stack
|
|
direction="row"
|
|
sx={{
|
|
justifyContent: 'space-between',
|
|
alignItems: 'center',
|
|
gap: 2,
|
|
}}
|
|
>
|
|
<Typography variant="body2" sx={{ fontWeight: '500' }}>
|
|
{country.name}
|
|
</Typography>
|
|
<Typography variant="body2" sx={{ color: 'text.secondary' }}>
|
|
{country.value}%
|
|
</Typography>
|
|
</Stack>
|
|
<LinearProgress
|
|
variant="determinate"
|
|
aria-label="Number of users by country"
|
|
value={country.value}
|
|
sx={{
|
|
[`& .${linearProgressClasses.bar}`]: {
|
|
backgroundColor: country.color,
|
|
},
|
|
}}
|
|
/>
|
|
</Stack>
|
|
</Stack>
|
|
))}
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|