WarStatsPage works in 100%
This commit is contained in:
parent
a16e2ea752
commit
48da47a8ab
|
@ -9,6 +9,7 @@
|
|||
"@material-ui/icons": "^4.11.0",
|
||||
"@material-ui/lab": "^4.0.0-alpha.57",
|
||||
"@material-ui/pickers": "3.2.10",
|
||||
"@nivo/bar": "0.64.0",
|
||||
"@nivo/core": "0.64.0",
|
||||
"@nivo/line": "0.64.0",
|
||||
"@testing-library/jest-dom": "^5.11.4",
|
||||
|
|
64
src/common/Chart/BarChart.tsx
Normal file
64
src/common/Chart/BarChart.tsx
Normal file
|
@ -0,0 +1,64 @@
|
|||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { LINE_CHART } from '@config/namespaces';
|
||||
import { darkTheme } from './theme';
|
||||
|
||||
import { ResponsiveBar, BarSvgProps } from '@nivo/bar';
|
||||
import { BasicTooltip } from '@nivo/tooltip';
|
||||
import { Box, Typography } from '@material-ui/core';
|
||||
import { Skeleton } from '@material-ui/lab';
|
||||
|
||||
export interface Props extends BarSvgProps {
|
||||
loading?: boolean;
|
||||
}
|
||||
|
||||
const BarChart = ({ data, loading, tooltipFormat, ...rest }: Props) => {
|
||||
const { t } = useTranslation(LINE_CHART);
|
||||
|
||||
if (loading) {
|
||||
return <Skeleton height="100%" variant="rect" />;
|
||||
}
|
||||
|
||||
if (data.length === 0) {
|
||||
return (
|
||||
<Box
|
||||
display="flex"
|
||||
justifyContent="center"
|
||||
height="100%"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography variant="h4" align="center">
|
||||
{t('emptyDataSourceMessage')}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<ResponsiveBar
|
||||
data={data}
|
||||
tooltipFormat={tooltipFormat}
|
||||
tooltip={props => {
|
||||
return (
|
||||
<BasicTooltip
|
||||
{...props}
|
||||
enableChip
|
||||
id={
|
||||
typeof props.data[`${props.id}Label`] === 'string'
|
||||
? props.data[`${props.id}Label`]
|
||||
: `${props.id} - ${props.indexValue}`
|
||||
}
|
||||
value={
|
||||
typeof tooltipFormat === 'function'
|
||||
? tooltipFormat(props.value)
|
||||
: props.value
|
||||
}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
{...rest}
|
||||
theme={darkTheme}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default BarChart;
|
|
@ -6,7 +6,6 @@ import { darkTheme } from './theme';
|
|||
import { ResponsiveLine, LineSvgProps } from '@nivo/line';
|
||||
import { Box, Typography } from '@material-ui/core';
|
||||
import { Skeleton } from '@material-ui/lab';
|
||||
import PointTooltip from './PointTooltip';
|
||||
|
||||
export interface Props extends LineSvgProps {
|
||||
loading?: boolean;
|
||||
|
@ -35,7 +34,7 @@ const LineChart = ({ data, loading, ...rest }: Props) => {
|
|||
}
|
||||
return (
|
||||
<ResponsiveLine
|
||||
tooltip={PointTooltip}
|
||||
// tooltip={PointTooltip}
|
||||
data={data}
|
||||
{...rest}
|
||||
theme={darkTheme}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import React from 'react';
|
||||
import { Tooltip } from '@material-ui/core';
|
||||
import { PointTooltipProps } from '@nivo/line';
|
||||
import { BarTooltipDatum } from '@nivo/bar';
|
||||
|
||||
function PointTooltip(props: PointTooltipProps) {
|
||||
function PointTooltip(props: PointTooltipProps | BarTooltipDatum) {
|
||||
const title =
|
||||
'point' in props
|
||||
? `X: ${props.point.data.xFormatted}, Y: ${props.point.data.yFormatted}`
|
||||
: `${props.indexValue} - ${props.value}`;
|
||||
console.log(props);
|
||||
return (
|
||||
<Tooltip
|
||||
open
|
||||
placement="top"
|
||||
arrow
|
||||
title={`X: ${props.point.data.xFormatted}, Y: ${props.point.data.yFormatted}`}
|
||||
>
|
||||
<Tooltip open placement="top" arrow title={title}>
|
||||
<div></div>
|
||||
</Tooltip>
|
||||
);
|
||||
|
|
|
@ -12,6 +12,12 @@ export const darkTheme: Theme = {
|
|||
strokeWidth: 1,
|
||||
},
|
||||
},
|
||||
textColor: '#fff',
|
||||
tooltip: {
|
||||
container: {
|
||||
backgroundColor: '#000',
|
||||
},
|
||||
},
|
||||
axis: {
|
||||
legend: {
|
||||
text: {
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
Map as MapIcon,
|
||||
Grade as GradeIcon,
|
||||
Beenhere as BeenhereIcon,
|
||||
Fireplace as FireplaceIcon,
|
||||
} from '@material-ui/icons';
|
||||
import DevNote from '@common/DevNote/DevNote';
|
||||
import Nav from './components/Nav/Nav';
|
||||
|
@ -123,6 +124,13 @@ const Sidebar = ({ t, className, open, variant, onClose, onOpen }: Props) => {
|
|||
Icon: <MapIcon color="inherit" />,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
name: t('pageLayout.sidebar.routes.warStats'),
|
||||
to: ROUTES.SERVER_PAGE.WAR_STATS_PAGE,
|
||||
params: { key },
|
||||
Icon: <FireplaceIcon color="inherit" />,
|
||||
exact: true,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
|
|
|
@ -22,19 +22,21 @@ import ServerPageLayout from '@features/ServerPage/common/PageLayout/PageLayout'
|
|||
import Spinner from '@common/Spinner/Spinner';
|
||||
import Card from './components/Card/Card';
|
||||
import OneSide from './components/OneSide/OneSide';
|
||||
import Result from './components/Result/Result';
|
||||
import Results from './components/Results/Results';
|
||||
|
||||
import {
|
||||
EnnoblementsQueryResult,
|
||||
EnnoblementsQueryVariables,
|
||||
Result as ResultT,
|
||||
Results as ResultsT,
|
||||
SideResult,
|
||||
Player,
|
||||
Tribe,
|
||||
} from './types';
|
||||
|
||||
function WarStatsPage() {
|
||||
const now = useRef(new Date());
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [result, setResult] = useState<ResultT | null>(null);
|
||||
const [results, setResults] = useState<ResultsT | null>(null);
|
||||
const [query, setQuery] = useQueryParams({
|
||||
ennobledAtGTE: withDefault(DateTimeParam, subDays(now.current, 1)),
|
||||
ennobledAtLTE: withDefault(DateTimeParam, now.current),
|
||||
|
@ -70,13 +72,17 @@ function WarStatsPage() {
|
|||
totalGained = 0,
|
||||
totalLost = 0,
|
||||
tribesGained = 0,
|
||||
playersGained = 0
|
||||
playersGained = 0,
|
||||
players: Player[] = [],
|
||||
tribes: Tribe[] = []
|
||||
): SideResult => {
|
||||
return {
|
||||
gained: totalGained,
|
||||
lost: totalLost,
|
||||
againstOppositeSide: tribesGained + playersGained,
|
||||
difference: Math.abs(totalGained - totalLost),
|
||||
difference: totalGained - totalLost,
|
||||
players,
|
||||
tribes,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -171,15 +177,19 @@ function WarStatsPage() {
|
|||
data.sideOneTotalGained?.total,
|
||||
data.sideOneTotalLost?.total,
|
||||
data.sideOneTribes?.total,
|
||||
data.sideOnePlayers?.total
|
||||
data.sideOnePlayers?.total,
|
||||
sideOnePlayers,
|
||||
sideOneTribes
|
||||
);
|
||||
const computedSideTwoResult: SideResult = getSideResult(
|
||||
data.sideTwoTotalGained?.total,
|
||||
data.sideTwoTotalLost?.total,
|
||||
data.sideTwoTribes?.total,
|
||||
data.sideTwoPlayers?.total
|
||||
data.sideTwoPlayers?.total,
|
||||
sideTwoPlayers,
|
||||
sideTwoTribes
|
||||
);
|
||||
setResult({
|
||||
setResults({
|
||||
sideOne: computedSideOneResult,
|
||||
sideTwo: computedSideTwoResult,
|
||||
difference: Math.abs(
|
||||
|
@ -303,9 +313,9 @@ function WarStatsPage() {
|
|||
</Button>
|
||||
</Typography>
|
||||
</Grid>
|
||||
{result && (
|
||||
{results && (
|
||||
<Grid item xs={12}>
|
||||
<Result data={result} />
|
||||
<Results data={results} server={server.key} />
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
|
|
|
@ -164,7 +164,7 @@ function OneSide({
|
|||
</Typography>
|
||||
<div>
|
||||
<Typography variant="h5" align="center" gutterBottom>
|
||||
{t('oneSide.players')}
|
||||
{t('players')}
|
||||
</Typography>
|
||||
<Autocomplete
|
||||
{...autocompleteProps}
|
||||
|
@ -189,7 +189,7 @@ function OneSide({
|
|||
</div>
|
||||
<div>
|
||||
<Typography variant="h5" align="center" gutterBottom>
|
||||
{t('oneSide.tribes')}
|
||||
{t('tribes')}
|
||||
</Typography>
|
||||
<Autocomplete
|
||||
{...autocompleteProps}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { SERVER_PAGE } from '@config/namespaces';
|
||||
|
||||
import { Card, CardContent, Typography } from '@material-ui/core';
|
||||
import { Result as ResultT } from '../../types';
|
||||
|
||||
export interface Props {
|
||||
data: ResultT;
|
||||
}
|
||||
|
||||
function Result({ data }: Props) {
|
||||
const { t } = useTranslation(SERVER_PAGE.WAR_STATS_PAGE);
|
||||
console.log(data);
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Typography variant="h4" align="center">
|
||||
{t('sections.result')}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export default Result;
|
|
@ -0,0 +1,11 @@
|
|||
import React from 'react';
|
||||
|
||||
export interface Props {
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
function ChartWrapper({ children }: Props) {
|
||||
return <div style={{ height: '400px' }}>{children}</div>;
|
||||
}
|
||||
|
||||
export default ChartWrapper;
|
|
@ -0,0 +1,67 @@
|
|||
import React from 'react';
|
||||
import formatNumber from '@utils/formatNumber';
|
||||
import * as ROUTES from '@config/routes';
|
||||
|
||||
import { Typography } from '@material-ui/core';
|
||||
import Link from '@common/Link/Link';
|
||||
import { TFunction } from 'i18next';
|
||||
import { SideResult } from '../../types';
|
||||
|
||||
export interface Props {
|
||||
data: SideResult;
|
||||
t: TFunction;
|
||||
server: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
function OneSideResult({ data, t, server, title }: Props) {
|
||||
return (
|
||||
<div>
|
||||
<Typography variant="h5" gutterBottom>
|
||||
{title}
|
||||
</Typography>
|
||||
{data.players.length > 0 && (
|
||||
<Typography>
|
||||
{t('players')}:{' '}
|
||||
{data.players.map(player => (
|
||||
<Link
|
||||
key={player.id}
|
||||
to={ROUTES.SERVER_PAGE.PLAYER_PAGE.INDEX_PAGE}
|
||||
params={{ id: player.id, key: server }}
|
||||
>
|
||||
{player.name}{' '}
|
||||
</Link>
|
||||
))}
|
||||
</Typography>
|
||||
)}
|
||||
{data.tribes.length > 0 && (
|
||||
<Typography>
|
||||
{t('tribes')}:{' '}
|
||||
{data.tribes.map(tribe => (
|
||||
<Link
|
||||
key={tribe.id}
|
||||
to={ROUTES.SERVER_PAGE.TRIBE_PAGE.INDEX_PAGE}
|
||||
params={{ id: tribe.id, key: server }}
|
||||
>
|
||||
{tribe.tag}{' '}
|
||||
</Link>
|
||||
))}
|
||||
</Typography>
|
||||
)}
|
||||
<Typography>
|
||||
{t('results.gained')}:{' '}
|
||||
<strong>{formatNumber('commas', data.gained)}</strong>
|
||||
</Typography>
|
||||
<Typography>
|
||||
{t('results.lost')}:{' '}
|
||||
<strong>{formatNumber('commas', data.lost)}</strong>
|
||||
</Typography>
|
||||
<Typography>
|
||||
{t('results.difference')}:{' '}
|
||||
<strong>{formatNumber('commas', data.difference)}</strong>
|
||||
</Typography>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default OneSideResult;
|
|
@ -0,0 +1,137 @@
|
|||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import formatNumber from '@utils/formatNumber';
|
||||
import { SERVER_PAGE } from '@config/namespaces';
|
||||
|
||||
import { useTheme } from '@material-ui/core/styles';
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
Typography,
|
||||
useMediaQuery,
|
||||
Grid,
|
||||
} from '@material-ui/core';
|
||||
import BarChart from '@common/Chart/BarChart';
|
||||
import OneSideResult from './OneSideResult';
|
||||
import ChartWrapper from './ChartWrapper';
|
||||
|
||||
import { Results as ResultsT } from '../../types';
|
||||
|
||||
export interface Props {
|
||||
data: ResultsT;
|
||||
server: string;
|
||||
}
|
||||
|
||||
function Results({ data, server }: Props) {
|
||||
const theme = useTheme();
|
||||
const isWidthDown750 = useMediaQuery(theme.breakpoints.down(750));
|
||||
const { t } = useTranslation(SERVER_PAGE.WAR_STATS_PAGE);
|
||||
const tooltipFormat = (v: string | number | Date) =>
|
||||
typeof v === 'string' || typeof v === 'number'
|
||||
? formatNumber('commas', v)
|
||||
: v.toLocaleString();
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Typography variant="h4" align="center" gutterBottom>
|
||||
{t('sections.results')}
|
||||
</Typography>
|
||||
<Grid container spacing={1}>
|
||||
<Grid item xs={12} sm={4}>
|
||||
<OneSideResult
|
||||
server={server}
|
||||
title={t('results.sideOne')}
|
||||
data={data.sideOne}
|
||||
t={t}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={4}>
|
||||
<OneSideResult
|
||||
server={server}
|
||||
title={t('results.sideTwo')}
|
||||
data={data.sideTwo}
|
||||
t={t}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={4}>
|
||||
<Typography variant="h5" gutterBottom>
|
||||
{t('results.ennoblementsAgainstOppositeSide')}
|
||||
</Typography>
|
||||
<Typography>
|
||||
{t('results.sideOne')}:{' '}
|
||||
<strong>
|
||||
{formatNumber('commas', data.sideOne.againstOppositeSide)}
|
||||
</strong>
|
||||
</Typography>
|
||||
<Typography>
|
||||
{t('results.sideTwo')}:{' '}
|
||||
<strong>
|
||||
{formatNumber('commas', data.sideTwo.againstOppositeSide)}
|
||||
</strong>
|
||||
</Typography>
|
||||
<Typography>
|
||||
{t('results.difference')}:{' '}
|
||||
<strong>{formatNumber('commas', data.difference)}</strong>
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<ChartWrapper>
|
||||
<BarChart
|
||||
data={[
|
||||
{
|
||||
id: t('results.sideOne'),
|
||||
val1: data.sideOne.gained,
|
||||
val1Label: t('results.chart.sideOneGained'),
|
||||
val2: data.sideOne.lost,
|
||||
val2Label: t('results.chart.sideOneLost'),
|
||||
},
|
||||
{
|
||||
id: t('results.sideTwo'),
|
||||
val1: data.sideTwo.gained,
|
||||
val1Label: t('results.chart.sideTwoGained'),
|
||||
val2: data.sideTwo.lost,
|
||||
val2Label: t('results.chart.sideTwoLost'),
|
||||
},
|
||||
{
|
||||
id: t('results.ennoblementsAgainstOppositeSide'),
|
||||
val1: data.sideOne.againstOppositeSide,
|
||||
val1Label: t('results.sideOne'),
|
||||
val2: data.sideTwo.againstOppositeSide,
|
||||
val2Label: t('results.sideTwo'),
|
||||
},
|
||||
]}
|
||||
keys={['val1', 'val2']}
|
||||
colors={['green', 'red']}
|
||||
indexBy="id"
|
||||
margin={{ top: 30, right: 35, bottom: 30, left: 35 }}
|
||||
padding={0.1}
|
||||
groupMode="grouped"
|
||||
tooltipFormat={tooltipFormat}
|
||||
axisTop={null}
|
||||
axisRight={null}
|
||||
axisBottom={{
|
||||
tickSize: 0,
|
||||
tickPadding: 5,
|
||||
tickRotation: 0,
|
||||
format: isWidthDown750 ? () => '' : undefined,
|
||||
}}
|
||||
axisLeft={{
|
||||
tickSize: 0,
|
||||
tickPadding: 5,
|
||||
tickRotation: 0,
|
||||
format: tooltipFormat,
|
||||
}}
|
||||
labelSkipWidth={12}
|
||||
labelSkipHeight={12}
|
||||
animate={true}
|
||||
motionStiffness={90}
|
||||
motionDamping={15}
|
||||
/>
|
||||
</ChartWrapper>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export default Results;
|
|
@ -66,9 +66,11 @@ export type SideResult = {
|
|||
lost: number;
|
||||
difference: number;
|
||||
againstOppositeSide: number;
|
||||
players: Player[];
|
||||
tribes: Tribe[];
|
||||
};
|
||||
|
||||
export type Result = {
|
||||
export type Results = {
|
||||
sideOne: SideResult;
|
||||
sideTwo: SideResult;
|
||||
difference: number;
|
||||
|
|
|
@ -23,6 +23,7 @@ const translations = {
|
|||
},
|
||||
ennoblements: 'Ennoblements',
|
||||
map: 'Map tool',
|
||||
warStats: 'War stats',
|
||||
},
|
||||
serverInfo: {
|
||||
numberOfPlayers: '{{num}} player',
|
||||
|
|
|
@ -8,17 +8,29 @@ const translations = {
|
|||
settings: 'Settings',
|
||||
sideOne: 'Side one',
|
||||
sideTwo: 'Side two',
|
||||
result: 'Result',
|
||||
},
|
||||
oneSide: {
|
||||
players: 'Players',
|
||||
tribes: 'Tribes',
|
||||
results: 'Results',
|
||||
},
|
||||
players: 'Players',
|
||||
tribes: 'Tribes',
|
||||
loading: 'Loading...',
|
||||
noOptions: 'No options',
|
||||
buttons: {
|
||||
generateStats: 'Generate stats',
|
||||
},
|
||||
results: {
|
||||
sideOne: 'Side one',
|
||||
sideTwo: 'Side two',
|
||||
lost: 'Lost',
|
||||
gained: 'Gained',
|
||||
difference: 'Difference',
|
||||
ennoblementsAgainstOppositeSide: 'Ennoblements against opposite side',
|
||||
chart: {
|
||||
sideOneGained: 'Side one - gained',
|
||||
sideOneLost: 'Side one - lost',
|
||||
sideTwoGained: 'Side two - gained',
|
||||
sideTwoLost: 'Side two - lost',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default translations;
|
||||
|
|
|
@ -16,6 +16,7 @@ const init = (): i18nT => {
|
|||
load: 'languageOnly',
|
||||
detection: {
|
||||
order: ['subdomain'],
|
||||
lookupFromSubdomainIndex: 0,
|
||||
},
|
||||
resources: {
|
||||
en,
|
||||
|
|
|
@ -23,6 +23,7 @@ const translations = {
|
|||
},
|
||||
ennoblements: 'Przejęcia',
|
||||
map: 'Narzędzie mapy',
|
||||
warStats: 'Statystyki wojenne',
|
||||
},
|
||||
serverInfo: {
|
||||
numberOfPlayers_0: '{{num}} gracz',
|
||||
|
|
|
@ -8,17 +8,29 @@ const translations = {
|
|||
settings: 'Opcje',
|
||||
sideOne: 'Strona pierwsza',
|
||||
sideTwo: 'Strona druga',
|
||||
result: 'Wynik',
|
||||
},
|
||||
oneSide: {
|
||||
players: 'Gracze',
|
||||
tribes: 'Plemiona',
|
||||
results: 'Wyniki',
|
||||
},
|
||||
players: 'Gracze',
|
||||
tribes: 'Plemiona',
|
||||
loading: 'Ładowanie...',
|
||||
noOptions: 'Brak opcji',
|
||||
buttons: {
|
||||
generateStats: 'Wygeneruj statystyki',
|
||||
},
|
||||
results: {
|
||||
sideOne: 'Strona pierwsza',
|
||||
sideTwo: 'Strona druga',
|
||||
lost: 'Stracone',
|
||||
gained: 'Zdobyte',
|
||||
difference: 'Różnica',
|
||||
ennoblementsAgainstOppositeSide: 'Przejęcia przeciwnej strony',
|
||||
chart: {
|
||||
sideOneGained: 'Strona pierwsza - zdobyte',
|
||||
sideOneLost: 'Strona pierwsza - stracone',
|
||||
sideTwoGained: 'Strona druga - zdobyte',
|
||||
sideTwoLost: 'Strona druga - stracone',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default translations;
|
||||
|
|
20
yarn.lock
20
yarn.lock
|
@ -1428,6 +1428,24 @@
|
|||
d3-time-format "^2.1.3"
|
||||
react-spring "^8.0.27"
|
||||
|
||||
"@nivo/bar@0.64.0":
|
||||
version "0.64.0"
|
||||
resolved "https://registry.yarnpkg.com/@nivo/bar/-/bar-0.64.0.tgz#ed6e793792fe4de62878be3645a5c3e6d437a0d7"
|
||||
integrity sha512-/AFeuvlok5+Hx3umEEtBXU3I5Pmo9oauWeqBrEejsA2Vb/Te/tdsruiSBI6d2s69XVnGU0i/E9lmC7HmcIp+/Q==
|
||||
dependencies:
|
||||
"@nivo/annotations" "0.64.0"
|
||||
"@nivo/axes" "0.64.0"
|
||||
"@nivo/colors" "0.64.0"
|
||||
"@nivo/core" "0.64.0"
|
||||
"@nivo/legends" "0.64.0"
|
||||
"@nivo/scales" "0.64.0"
|
||||
"@nivo/tooltip" "0.64.0"
|
||||
d3-scale "^3.0.0"
|
||||
d3-shape "^1.2.2"
|
||||
lodash "^4.17.11"
|
||||
react-motion "^0.5.2"
|
||||
recompose "^0.30.0"
|
||||
|
||||
"@nivo/colors@0.64.0":
|
||||
version "0.64.0"
|
||||
resolved "https://registry.yarnpkg.com/@nivo/colors/-/colors-0.64.0.tgz#b754950809738bd8add710f56bcd344689347743"
|
||||
|
@ -4196,7 +4214,7 @@ d3-scale@^3.0.0:
|
|||
d3-time "1 - 2"
|
||||
d3-time-format "2 - 3"
|
||||
|
||||
d3-shape@^1.3.5:
|
||||
d3-shape@^1.2.2, d3-shape@^1.3.5:
|
||||
version "1.3.7"
|
||||
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7"
|
||||
integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==
|
||||
|
|
Reference in New Issue
Block a user