recharts#Cell TypeScript Examples
The following examples show how to use
recharts#Cell.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: RegionOverseasChart.tsx From covid19map with MIT License | 6 votes |
RegionOverseasChart = ({ data }: { data: any }) => {
const theme = useTheme();
const chartColors = [theme.navy, theme.yellow, "#a6e5e3"];
return (
<StyledRegionOverseasChart>
<h3>Overseas Travel</h3>
<div className="row">
<div>
<div className="chart-wrap">
<ResponsiveContainer width="100%" height="100%">
{/* @ts-ignore */}
<PieChart isAnimationActive={false}>
<Pie dataKey="count" data={data} outerRadius="100%">
{data.map((_: any, index: number) => (
<Cell
key={`cell-${index}`}
fill={chartColors[index % chartColors.length]}
/>
))}
</Pie>
</PieChart>
</ResponsiveContainer>
</div>
</div>
<div>
{data.map((item: any, i: number) => (
<LegendItem key={i} typeColor={chartColors[i]}>
{item.overseas}: <span>{item.count}</span>
</LegendItem>
))}
</div>
</div>
</StyledRegionOverseasChart>
);
}
Example #2
Source File: TransmissionChart.tsx From covid19map with MIT License | 6 votes |
TransmissionChart = ({ data = [] }) => {
const theme = useTheme();
const chartColors = [
theme.teal,
theme.green,
theme.navy,
theme.yellow,
"#956828",
];
return (
<StyledTransmissionChart>
<div className="head">Source of cases</div>
<div className="row">
<div className="chart-wrap">
<ResponsiveContainer width="100%" height="100%">
<PieChart>
<Pie dataKey="percent" data={data} outerRadius="100%">
{data.map((_, index) => (
<Cell
key={`cell-${index}`}
fill={chartColors[index % chartColors.length]}
/>
))}
</Pie>
</PieChart>
</ResponsiveContainer>
</div>
<div>
{data.map((item: any, i: number) => (
<LegendItem key={i} typeColor={chartColors[i]}>
{item.type}: <span>{item.percent}</span>
</LegendItem>
))}
</div>
</div>
</StyledTransmissionChart>
);
}
Example #3
Source File: PieChart.tsx From opensaas with MIT License | 6 votes |
PieChart: React.FC<PieChartProps> = (props: PieChartProps) => {
const { width, height, data = [], colors, pie } = props;
return (
<RechartsPieChart width={width} height={height}>
<Tooltip />
<Legend />
<Pie
data={data}
cx={pie?.cx}
cy={pie?.cy}
innerRadius={pie?.innerRadius}
outerRadius={pie?.outerRadius}
fill='#8884d8'
paddingAngle={pie?.paddingAngle}
dataKey='value'>
{data.map((_entry, index) => (
<Cell key={`cell-${index}`} fill={colors[index % colors.length]} />
))}
</Pie>
</RechartsPieChart>
);
}
Example #4
Source File: InternationalBarChart.tsx From covid19map with MIT License | 5 votes |
Ages = ({ data }: { data: any[] }) => {
const theme = useTheme();
const countries: any = {
NZL: { name: "NZ", color: theme.teal },
AUS: { name: "AU", color: theme.green },
USA: { name: "USA", color: theme.navy },
CHN: { name: "CHINA", color: "#317c3f" },
ITA: { name: "ITALY", color: "#956828" },
GBR: { name: "UK", color: "#d4b074" },
KOR: { name: "S.KOREA", color: theme.yellow },
};
const dataWithNames = data.map((item: any) => {
return {
...item,
name: countries[item.country].name,
country: countries[item.country],
};
});
dataWithNames.sort((x, y) => (x.per1m > y.per1m ? -1 : 1));
return (
<StyledAges>
<div className="head">Cases per 1 million</div>
<div className="chart-wrap">
<ResponsiveContainer width="100%" height="100%">
<BarChart
data={dataWithNames}
layout="vertical"
margin={{
top: 10,
right: 60,
left: 0,
bottom: 10,
}}
// @ts-ignore
isAnimationActive={false}
>
<XAxis type="number" hide />
<YAxis type="category" dataKey="name" interval={0} width={90} />
<Bar
dataKey="per1m"
fill="#8884d8"
label={{ position: "right", fill: theme.dark }}
minPointSize={2}
>
{dataWithNames.map((entry, index) => (
<Cell key={`cell-${index}`} fill={entry.country.color} />
))}
</Bar>
</BarChart>
</ResponsiveContainer>
</div>
</StyledAges>
);
}
Example #5
Source File: Profile.tsx From avalon.ist with MIT License | 4 votes |
render() {
const { initialHeight } = this;
const {
myname,
style: { themeLight },
} = this.props.match.params;
const theme = themeLight ? 'light' : 'dark';
const data: any[] = [];
// const { avatarStyle } = this.props.match.params.style;
const {
username,
nationality,
bio,
gameRating,
gameHistory,
games,
gameStats,
gameShots,
avatars,
showSpy,
redirect,
} = this.state;
for (const k in gameStats) {
const stat = gameStats[k];
data.push({
name: k.charAt(0).toUpperCase() + k.slice(1),
wins: stat[0],
total: stat[1],
Winrate: stat[1] === 0 ? 0 : Percent(stat[0] / stat[1]),
color: SPY_ROLES.has(k) ? '#ff6384' : '#36a2eb',
});
}
const country = countries.find((c) => c.text === nationality);
const totalWon = games[0];
const totalLost = games[1] - totalWon;
const winRate = games[1] > 0 ? Percent(totalWon / games[1]) : 0;
const shotRate = gameShots[1] > 0 ? Percent(gameShots[0] / gameShots[1]) : 0;
let countryFlag = <img alt={'UN'} src={UN_FLAG} />;
if (country && country.value != 'UN') {
if (country.value == 'LGBT') {
countryFlag = <img alt={'Stonewall'} src={STONEWALL_FLAG} />;
} else {
countryFlag = <Flag code={country.value} />;
}
}
return redirect ? (
<Redirect to="/profile-not-found" />
) : (
<div id="Background-2" className={`full ${theme}`}>
<Navbar username="" key={'Navbar'} />
<AvalonScrollbars>
<div id="Profile" style={{ minHeight: `${initialHeight}px` }}>
<div className="row">
<div id="user">
<img
src={showSpy ? avatars.spy : avatars.res}
alt={'Avatar'}
onMouseOver={this.onHover}
onMouseLeave={this.onStopHover}
/>
<div className="user-tag">
{countryFlag}
<p>
<b>{username}</b>
<br />
{nationality}
</p>
</div>
</div>
<div id="bio" className="bubble">
<AvalonScrollbars>
<ReactMarkdown
className="markdown"
allowedTypes={[
'text',
'paragraph',
'emphasis',
'strong',
'thematicBreak',
'blockquote',
'list',
'listItem',
'heading',
]}
>
{bio}
</ReactMarkdown>
</AvalonScrollbars>
</div>
</div>
<div className="row">
<div id="stats">
<h1>STATISTICS</h1>
<table>
<tbody>
<tr>
<th>Statistic</th>
<th>Value</th>
</tr>
<tr>
<td>Total Games Played</td>
<td>{games[1]}</td>
</tr>
<tr>
<td>Total Games Won</td>
<td>{totalWon}</td>
</tr>
<tr>
<td>Total Games Lost</td>
<td>{totalLost}</td>
</tr>
<tr>
<td>Total Win Rate</td>
<td>{winRate}%</td>
</tr>
<tr>
<td>Shot Accuracy</td>
<td>{shotRate}%</td>
</tr>
<tr>
<td>Rating</td>
<td>{gameRating}</td>
</tr>
</tbody>
</table>
</div>
<div id="graph">
<ResponsiveContainer width={'100%'} height={300}>
<BarChart
layout="vertical"
margin={{
top: 20,
right: 20,
bottom: 20,
left: 20,
}}
data={data}
>
<CartesianGrid strokeDasharray="1 1" />
<XAxis type="number" domain={[0, 100]} />
<YAxis type="category" width={100} dataKey="name" />
<Tooltip content={<CustomTooltip />} />
<Bar dataKey="Winrate" fill="#8884d8">
{data.map((entry, index) => (
<Cell key={`cell-${index}`} fill={entry.color} />
))}
</Bar>
</BarChart>
</ResponsiveContainer>
</div>
</div>
<div className="row">
<div id="history">
<h1>GAME HISTORY</h1>
<table>
<tbody>
<tr>
<th>Game</th>
<th>Role</th>
<th>Size</th>
<th>Winner</th>
<th>Date</th>
</tr>
{gameHistory
.slice(-10)
.reverse()
.map((g: any, i) => {
const date = new Date(g.date);
const month = ('00' + (date.getUTCMonth() + 1)).slice(-2);
const day = ('00' + date.getUTCDate()).slice(-2);
const year = date.getUTCFullYear();
return (
<tr key={'Game' + g.id}>
<td>
<Link to={'/game/' + g.id}>#{g.code}</Link>
</td>
<td>{g.role}</td>
<td>{g.size}</td>
<td>{g.winner ? 'Resistance' : 'Spy'}</td>
<td>
{year}-{month}-{day}
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
</div>
</AvalonScrollbars>
{myname === username ? (
<button
className="button-b edit-your-profile-with-this"
type="button"
onClick={this.onFormToggle}
>
<p>Edit Profile</p>
</button>
) : null}
{this.state.showForm ? (
<EditProfile
onExit={this.onFormToggle}
text="Submit"
nationality={nationality}
bio={bio}
title="EDIT YOUR PROFILE"
onSelect={this.onEdit}
/>
) : null}
</div>
);
}
Example #6
Source File: Balances.tsx From abrechnung with GNU Affero General Public License v3.0 | 4 votes |
export default function Balances({ group }) {
const theme: Theme = useTheme();
const isSmallScreen = useMediaQuery(theme.breakpoints.down("sm"));
const history = useHistory();
const personalAccounts = useRecoilValue(personalAccountsSeenByUser(group.id));
const clearingAccounts = useRecoilValue(clearingAccountsSeenByUser(group.id));
const balances = useRecoilValue(accountBalances(group.id));
const [selectedTab, setSelectedTab] = useState("1");
const colorGreen = theme.palette.mode === "light" ? theme.palette.success.light : theme.palette.success.dark;
const colorRed = theme.palette.mode === "light" ? theme.palette.error.light : theme.palette.error.dark;
const colorGreenInverted = theme.palette.mode === "dark" ? theme.palette.success.light : theme.palette.success.dark;
const colorRedInverted = theme.palette.mode === "dark" ? theme.palette.error.light : theme.palette.error.dark;
useTitle(`${group.name} - Balances`);
const chartData = personalAccounts.map((account) => {
return {
name: account.name,
balance: balances[account.id].balance,
totalPaid: balances[account.id].totalPaid,
totalConsumed: balances[account.id].totalConsumed,
id: account.id,
};
});
const unbalancedClearingAccounts = clearingAccounts
.filter((account) => balances[account.id].balance !== 0)
.map((account) => {
return {
name: account.name,
id: account.id,
balance: balances[account.id].balance,
};
});
const chartHeight = Object.keys(balances).length * 30 + 100;
// TODO determine the rendered width of the account names and take the maximum
const yaxiswidth = isSmallScreen
? Math.max(Math.max(...personalAccounts.map((account) => account.name.length)), 20)
: Math.max(...personalAccounts.map((account) => account.name.length)) * 7 + 5;
const handleBarClick = (data, event) => {
const id = data.activePayload[0].payload.id;
history.push(`/groups/${group.id}/accounts/${id}`);
};
return (
<MobilePaper>
<TabContext value={selectedTab}>
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
<TabList onChange={(event, idx) => setSelectedTab(idx)} centered>
<Tab label="Chart" value="1" />
<Tab label="Table" value="2" />
</TabList>
</Box>
<TabPanel value="1" sx={{ padding: { xs: 1, md: 2 } }}>
{personalAccounts.length === 0 && <Alert severity="info">No Accounts</Alert>}
{unbalancedClearingAccounts.length !== 0 && (
<Alert severity="info">
<AlertTitle>Some Clearing Accounts have remaining balances.</AlertTitle>
{unbalancedClearingAccounts.map((account) => (
<Typography variant="body2" key={account.id} component="span">
<>{account.name}:</>
<Typography
variant="body2"
component="span"
sx={{ color: account.balance < 0 ? colorRedInverted : colorGreenInverted }}
>
{account.balance.toFixed(2)} {group.currency_symbol}{" "}
</Typography>
</Typography>
))}
</Alert>
)}
{isSmallScreen ? (
<List>
{personalAccounts.map((account) => (
<>
<ListItemLink key={account.id} to={`/groups/${group.id}/accounts/${account.id}`}>
<ListItemText primary={account.name} />
<Typography
align="right"
variant="body2"
sx={{
color:
balances[account.id].balance < 0
? colorRedInverted
: colorGreenInverted,
}}
>
{balances[account.id].balance.toFixed(2)} {group.currency_symbol}
</Typography>
</ListItemLink>
<Divider key={account.id * 2} component="li" />
</>
))}
</List>
) : (
<div className="area-chart-wrapper" style={{ width: "100%", height: `${chartHeight}px` }}>
<ResponsiveContainer>
<BarChart
data={chartData}
margin={{
top: 20,
right: 20,
bottom: 20,
left: 20,
}}
layout="vertical"
onClick={handleBarClick}
>
<XAxis
stroke={theme.palette.text.primary}
type="number"
unit={group.currency_symbol}
/>
<YAxis
dataKey="name"
stroke={theme.palette.text.primary}
type="category"
width={yaxiswidth}
/>
<Tooltip
formatter={(label) =>
parseFloat(label).toFixed(2) + ` ${group.currency_symbol}`
}
labelStyle={{
color: theme.palette.text.primary,
}}
itemStyle={{
color: theme.palette.text.primary,
}}
contentStyle={{
backgroundColor: theme.palette.background.paper,
borderColor: theme.palette.divider,
borderRadius: theme.shape.borderRadius,
}}
/>
<Bar dataKey="balance">
{chartData.map((entry, index) => {
return (
<Cell
key={`cell-${index}`}
fill={entry["balance"] >= 0 ? colorGreen : colorRed}
/>
);
})}
<LabelList
dataKey={(entry) =>
`${entry["balance"].toFixed(2)}${group.currency_symbol}`
}
position="insideLeft"
fill={theme.palette.text.primary}
/>
</Bar>
</BarChart>
</ResponsiveContainer>
</div>
)}
</TabPanel>
<TabPanel value="2" sx={{ padding: { xs: 1, md: 2 } }}>
<BalanceTable group={group} />
</TabPanel>
</TabContext>
</MobilePaper>
);
}
Example #7
Source File: index.tsx From liferay-grow with MIT License | 4 votes |
SkillDetailSummay: React.FC<SkillDetailSummaryProps> = ({
slug,
summary,
}) => {
const i18n = useLang();
const [visible, setVisible] = useState(false);
const [matriz, setMatriz] = useState<Summary>({} as Summary);
const { observer, onClose } = useModal({
onClose: () => setVisible(!visible),
});
// Filter Empty Results from Summary
const summaryData = summary.filter(({ value }) => value);
const getFromattedTooltip = (value: number) => {
const valueString = value.toString();
return i18n.sub(value > 1 ? 'x-members' : 'x-member', valueString);
};
const hasSummary = !!summaryData.length;
return (
<Panel displayType="unstyled" title={i18n.get('summary')}>
{hasSummary ? (
<>
<PieChart className="summary-chart" width={420} height={280}>
<Pie
data={summaryData}
dataKey="value"
nameKey="name"
cx="50%"
cy="50%"
innerRadius={70}
outerRadius={120}
paddingAngle={0}
>
{summary.map((_, index) => (
<Cell
key={index}
fill={COLORS[index]}
onClick={() => console.log(summary)}
/>
))}
</Pie>
<Tooltip formatter={getFromattedTooltip} />
<Legend
align="right"
iconSize={16}
formatter={(value) => (
<ClayButton
displayType="unstyled"
onClick={() => {
setVisible(true);
const matriz = summary.find(({ name }) => name === value);
setMatriz(matriz);
}}
>
<span className="legend-text">{value}</span>
</ClayButton>
)}
iconType="square"
layout="vertical"
verticalAlign="middle"
/>
</PieChart>
<Modal
visible={visible}
observer={observer}
title={matriz.name}
subtitle={
matriz.description
? `${i18n.sub('description-x-x', [
matriz.name,
matriz.description,
])}`
: null
}
>
<ListMembers onClose={onClose} matriz={matriz} slug={slug} />
</Modal>
</>
) : (
<EmptyState title={i18n.get('there-are-no-members-yet')} />
)}
</Panel>
);
}
Example #8
Source File: DriveInfoItem.tsx From console with GNU Affero General Public License v3.0 | 4 votes |
DriveInfoItem = ({ drive }: ICardProps) => {
const freeSpace = drive.totalSpace - drive.usedSpace;
const plotValues = [
{ value: freeSpace, color: "#D6D6D6", label: "Free Space" },
{
value: drive.usedSpace,
color: capacityColors(drive.usedSpace, drive.totalSpace),
label: "Used Space",
},
];
return (
<Box
sx={{
display: "flex",
flex: 1,
alignItems: "center",
paddingBottom: "10px",
padding: "20px",
border: "1px solid #eaeaea",
}}
>
<Box
sx={{
display: "flex",
flexFlow: "column",
marginLeft: "10px",
flex: 1,
}}
>
<Box
sx={{
fontSize: "14px",
fontWeight: 400,
display: "flex",
alignItems: "center",
"& .min-icon": {
marginRight: "10px",
height: "10px",
width: "10px",
fill: driveStatusColor(drive.state),
flexShrink: 0,
},
"& .drive-endpoint": {
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "normal",
wordBreak: "break-all",
marginRight: "8px",
fontWeight: 600,
fontSize: {
md: "16px",
xs: "10px",
},
},
}}
>
<div className="drive-endpoint">{drive.endpoint || ""}</div>
{drive.state && <CircleIcon />}
</Box>
<Box
sx={{
flex: 1,
display: "flex",
alignItems: "center",
paddingLeft: "20px",
marginTop: "10px",
flexFlow: {
sm: "row",
xs: "column",
},
"& .info-label": {
color: "#5E5E5E",
fontSize: "12px",
textAlign: "center",
},
"& .info-value": {
fontSize: "18px",
color: "#07193E",
display: "flex",
fontWeight: 500,
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
},
}}
>
<Box sx={{ flex: 1 }}>
<div style={{ position: "relative", width: 110, height: 110 }}>
<span
style={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
fontWeight: "bold",
color: "#000",
fontSize: 12,
}}
>
{niceBytesInt(drive.usedSpace)}
</span>
<div>
<PieChart width={110} height={110}>
<Pie
data={plotValues}
cx={"50%"}
cy={"50%"}
dataKey="value"
outerRadius={50}
innerRadius={40}
startAngle={-70}
endAngle={360}
animationDuration={1}
>
{plotValues.map((entry, index) => (
<Cell key={`cellCapacity-${index}`} fill={entry.color} />
))}
</Pie>
</PieChart>
</div>
</div>
</Box>
<Box
sx={{
display: "flex",
gap: "5%",
alignItems: "center",
flex: 2,
flexGrow: 1,
}}
>
<Box
sx={{
display: "flex",
flexFlow: "column",
}}
>
<div className="info-value">
{niceBytes(
drive.totalSpace ? drive.totalSpace.toString() : "0"
)}
</div>
<label className="info-label">Capacity</label>
</Box>
<Box
sx={{
display: "flex",
flexFlow: "column",
}}
>
<div className="info-value">
{niceBytes(drive.usedSpace ? drive.usedSpace.toString() : "0")}
</div>
<label className="info-label">Used</label>
</Box>
<Box
sx={{
display: "flex",
flexFlow: "column",
}}
>
<div className="info-value">
{niceBytes(
drive.availableSpace ? drive.availableSpace.toString() : "0"
)}
</div>
<label className="info-label">Available</label>
</Box>
</Box>
</Box>
</Box>
</Box>
);
}
Example #9
Source File: ReportedUsage.tsx From console with GNU Affero General Public License v3.0 | 4 votes |
ReportedUsage = ({
usageValue,
total,
unit,
}: {
usageValue: string;
total: number | string;
unit: string;
}) => {
const plotValues = [
{ value: total, color: "#D6D6D6", label: "Free Space" },
{
value: usageValue,
color: "#073052",
label: "Used Space",
},
];
return (
<Box
sx={{
maxHeight: "110px",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
fontSize: "19px",
padding: "10px",
"& .unit-value": {
fontSize: "50px",
color: "#07193E",
},
"& .unit-type": {
fontSize: "18px",
color: "#5E5E5E",
marginTop: "20px",
marginLeft: "5px",
},
"& .usage-label": {
display: "flex",
alignItems: "center",
fontSize: "16px",
fontWeight: 600,
marginRight: "20px",
marginTop: "-10px",
"& .min-icon": {
marginLeft: "10px",
height: 16,
width: 16,
},
},
}}
>
<Box>
<div className="usage-label">
<span>Reported Usage</span>
</div>
<Tooltip title={`${usageValue} Bytes`}>
<label
className={"unit-value"}
style={{
fontWeight: 600,
}}
>
{total}
</label>
</Tooltip>
<label className={"unit-type"}>{unit}</label>
</Box>
<Box>
<Box sx={{ flex: 1 }}>
<div
style={{
position: "relative",
width: 105,
height: 105,
top: "-8px",
}}
>
<div>
<PieChart width={105} height={105}>
<Pie
data={plotValues}
cx={"50%"}
cy={"50%"}
dataKey="value"
outerRadius={45}
innerRadius={35}
startAngle={-70}
endAngle={360}
animationDuration={1}
>
{plotValues.map((entry, index) => (
<Cell key={`cellCapacity-${index}`} fill={entry.color} />
))}
</Pie>
</PieChart>
</div>
</div>
</Box>
</Box>
</Box>
);
}
Example #10
Source File: BarChartWidget.tsx From console with GNU Affero General Public License v3.0 | 4 votes |
BarChartWidget = ({
classes,
title,
panelItem,
timeStart,
timeEnd,
propLoading,
apiPrefix,
zoomActivated = false,
}: IBarChartWidget) => {
const dispatch = useDispatch();
const [loading, setLoading] = useState<boolean>(true);
const [data, setData] = useState<any>([]);
const [result, setResult] = useState<IDashboardPanel | null>(null);
useEffect(() => {
if (propLoading) {
setLoading(true);
}
}, [propLoading]);
useEffect(() => {
if (loading) {
let stepCalc = 0;
if (timeStart !== null && timeEnd !== null) {
const secondsInPeriod = timeEnd.unix() - timeStart.unix();
const periods = Math.floor(secondsInPeriod / 60);
stepCalc = periods < 1 ? 15 : periods;
}
api
.invoke(
"GET",
`/api/v1/${apiPrefix}/info/widgets/${
panelItem.id
}/?step=${stepCalc}&${
timeStart !== null ? `&start=${timeStart.unix()}` : ""
}${timeStart !== null && timeEnd !== null ? "&" : ""}${
timeEnd !== null ? `end=${timeEnd.unix()}` : ""
}`
)
.then((res: any) => {
const widgetsWithValue = widgetDetailsToPanel(res, panelItem);
setData(widgetsWithValue.data);
setResult(widgetsWithValue);
setLoading(false);
})
.catch((err: ErrorResponseHandler) => {
dispatch(setErrorSnackMessage(err));
setLoading(false);
});
}
}, [loading, panelItem, timeEnd, timeStart, dispatch, apiPrefix]);
const barChartConfiguration = result
? (result.widgetConfiguration as IBarChartConfiguration[])
: [];
let greatestIndex = 0;
let currentValue = 0;
if (barChartConfiguration.length === 1) {
const dataGraph = barChartConfiguration[0];
data.forEach((item: any, index: number) => {
if (item[dataGraph.dataKey] > currentValue) {
currentValue = item[dataGraph.dataKey];
greatestIndex = index;
}
});
}
const theme = useTheme();
const biggerThanMd = useMediaQuery(theme.breakpoints.up("md"));
return (
<div className={zoomActivated ? "" : classes.singleValueContainer}>
{!zoomActivated && (
<div className={classes.titleContainer}>
{title} <ExpandGraphLink panelItem={panelItem} />
</div>
)}
{loading && (
<div className={classes.loadingAlign}>
<Loader />
</div>
)}
{!loading && (
<div
className={
zoomActivated ? classes.zoomChartCont : classes.contentContainer
}
>
<ResponsiveContainer width="99%">
<BarChart
data={data as object[]}
layout={"vertical"}
barCategoryGap={1}
>
<XAxis type="number" hide />
<YAxis
dataKey="name"
type="category"
interval={0}
tick={<CustomizedAxisTick />}
tickLine={false}
axisLine={false}
width={150}
hide={!biggerThanMd}
style={{
fontSize: "12px",
fontWeight: 100,
}}
/>
{barChartConfiguration.map((bar) => (
<Bar
key={`bar-${bar.dataKey}`}
dataKey={bar.dataKey}
fill={bar.color}
background={bar.background}
barSize={zoomActivated ? 25 : 12}
>
{barChartConfiguration.length === 1 ? (
<Fragment>
{data.map((_: any, index: number) => (
<Cell
key={`chart-bar-${index.toString()}`}
fill={
index === greatestIndex
? bar.greatestColor
: bar.color
}
/>
))}
</Fragment>
) : null}
</Bar>
))}
<Tooltip
cursor={{ fill: "rgba(255, 255, 255, 0.3)" }}
content={
<BarChartTooltip
barChartConfiguration={barChartConfiguration}
/>
}
/>
</BarChart>
</ResponsiveContainer>
</div>
)}
</div>
);
}
Example #11
Source File: CapacityItem.tsx From console with GNU Affero General Public License v3.0 | 4 votes |
CapacityItem = ({
value,
timeStart,
timeEnd,
propLoading,
apiPrefix,
}: {
value: IDashboardPanel;
timeStart: any;
timeEnd: any;
propLoading: boolean;
apiPrefix: string;
}) => {
const dispatch = useDispatch();
const [loading, setLoading] = useState<boolean>(true);
const [totalUsableFree, setTotalUsableFree] = useState<number>(0);
const [totalUsed, setTotalUsed] = useState<number>(0);
const [totalUsable, setTotalUsable] = useState<number>(0);
useEffect(() => {
if (propLoading) {
setLoading(true);
}
}, [propLoading]);
useEffect(() => {
if (loading) {
let stepCalc = 0;
if (timeStart !== null && timeEnd !== null) {
const secondsInPeriod = timeEnd.unix() - timeStart.unix();
const periods = Math.floor(secondsInPeriod / 60);
stepCalc = periods < 1 ? 15 : periods;
}
api
.invoke(
"GET",
`/api/v1/${apiPrefix}/info/widgets/${value.id}/?step=${stepCalc}&${
timeStart !== null ? `&start=${timeStart.unix()}` : ""
}${timeStart !== null && timeEnd !== null ? "&" : ""}${
timeEnd !== null ? `end=${timeEnd.unix()}` : ""
}`
)
.then((res: any) => {
const widgetsWithValue = widgetDetailsToPanel(res, value);
let tUsable = 0;
let tUsed = 0;
let tFree = 0;
widgetsWithValue.data.forEach((eachArray: any[]) => {
eachArray.forEach((itemSum) => {
switch (itemSum.legend) {
case "Total Usable":
tUsable += itemSum.value;
break;
case "Used Space":
tUsed += itemSum.value;
break;
case "Usable Free":
tFree += itemSum.value;
break;
}
});
});
setTotalUsableFree(tFree);
setTotalUsed(tUsed);
setTotalUsable(tUsable);
setLoading(false);
})
.catch((err: ErrorResponseHandler) => {
dispatch(setErrorSnackMessage(err));
setLoading(false);
});
}
}, [loading, value, timeEnd, timeStart, dispatch, apiPrefix]);
const usedConvert = calculateBytes(totalUsed, true, false);
const plotValues = [
{
value: totalUsableFree,
color: "#D6D6D6",
label: "Usable Available Space",
},
{
value: totalUsed,
color: capacityColors(totalUsed, totalUsable),
label: "Used Space",
},
];
return (
<Box
sx={{
flex: 1,
display: "flex",
alignItems: "center",
flexFlow: {
sm: "row",
xs: "column",
},
}}
>
<Box
sx={{
fontSize: "16px",
fontWeight: 600,
alignSelf: {
xs: "flex-start",
},
}}
>
Capacity
</Box>
<Box
sx={{
position: "relative",
width: 110,
height: 110,
marginLeft: {
sm: "auto",
xs: "",
},
}}
>
<Box
sx={{
position: "absolute",
display: "flex",
flexFlow: "column",
alignItems: "center",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
fontWeight: "bold",
color: "#000",
fontSize: 12,
}}
>
{niceBytesInt(totalUsableFree)}
<br />
<Box
sx={{
color: "#8F9090",
fontSize: "10px",
display: "flex",
flexFlow: "column",
alignItems: "center",
textAlign: "center",
}}
>
Current Usable Capacity
</Box>
</Box>
<PieChart width={110} height={110}>
<Pie
data={plotValues}
cx={"50%"}
cy={"50%"}
dataKey="value"
outerRadius={50}
innerRadius={40}
startAngle={-70}
endAngle={360}
animationDuration={1}
>
{plotValues.map((entry, index) => (
<Cell key={`cellCapacity-${index}`} fill={entry.color} />
))}
</Pie>
</PieChart>
</Box>
<Box
sx={{
display: "flex",
alignItems: "center",
marginLeft: {
sm: "auto",
xs: "",
},
}}
>
<Box>
<Box
sx={{
color: "#5E5E5E",
fontWeight: "bold",
fontSize: "14px",
}}
>
Used:
</Box>
<Box
sx={{
display: "flex",
"& .value": {
fontSize: "50px",
fontFamily: "Lato",
fontWeight: 600,
alignSelf: "flex-end",
lineHeight: 1,
},
"& .unit": {
color: "#5E5E5E",
fontWeight: "bold",
fontSize: "14px",
marginLeft: "12px",
alignSelf: "flex-end",
},
}}
>
<div className="value">{usedConvert.total}</div>
<div className="unit">{usedConvert.unit}</div>
</Box>
<Box
sx={{
marginTop: "5px",
"& .value": {
color: "#5E5E5E",
fontWeight: "bold",
fontSize: "14px",
textAlign: "right",
},
}}
>
<div className="value">Of: {niceBytesInt(totalUsable)}</div>
</Box>
</Box>
<Box
sx={{
marginLeft: "15px",
height: "100%",
display: "flex",
alignItems: "flex-start",
}}
>
<Box>
{loading ? (
<Loader style={{ width: "26px", height: "26px" }} />
) : (
<ReportedUsageIcon />
)}
</Box>
</Box>
</Box>
</Box>
);
}
Example #12
Source File: PieChartWidget.tsx From console with GNU Affero General Public License v3.0 | 4 votes |
PieChartWidget = ({
classes,
title,
panelItem,
timeStart,
timeEnd,
propLoading,
apiPrefix,
}: IPieChartWidget) => {
const dispatch = useDispatch();
const [loading, setLoading] = useState<boolean>(true);
const [dataInner, setDataInner] = useState<object[]>([]);
const [dataOuter, setDataOuter] = useState<object[]>([]);
const [result, setResult] = useState<IDashboardPanel | null>(null);
useEffect(() => {
if (propLoading) {
setLoading(true);
}
}, [propLoading]);
useEffect(() => {
if (loading) {
let stepCalc = 0;
if (timeStart !== null && timeEnd !== null) {
const secondsInPeriod = timeEnd.unix() - timeStart.unix();
const periods = Math.floor(secondsInPeriod / 60);
stepCalc = periods < 1 ? 15 : periods;
}
api
.invoke(
"GET",
`/api/v1/${apiPrefix}/info/widgets/${
panelItem.id
}/?step=${stepCalc}&${
timeStart !== null ? `&start=${timeStart.unix()}` : ""
}${timeStart !== null && timeEnd !== null ? "&" : ""}${
timeEnd !== null ? `end=${timeEnd.unix()}` : ""
}`
)
.then((res: any) => {
const widgetsWithValue = widgetDetailsToPanel(res, panelItem);
setDataInner(widgetsWithValue.data);
setDataOuter(widgetsWithValue.dataOuter as object[]);
setResult(widgetsWithValue);
setLoading(false);
})
.catch((err: ErrorResponseHandler) => {
dispatch(setErrorSnackMessage(err));
setLoading(false);
});
}
}, [loading, panelItem, timeEnd, timeStart, dispatch, apiPrefix]);
const pieChartConfiguration = result
? (result.widgetConfiguration as IPieChartConfiguration)
: [];
const middleLabel = result?.innerLabel;
const innerColors = get(pieChartConfiguration, "innerChart.colorList", []);
const outerColors = get(pieChartConfiguration, "outerChart.colorList", []);
return (
<div className={classes.singleValueContainer}>
<div className={classes.titleContainer}>{title}</div>
{loading && (
<div className={classes.loadingAlign}>
<Loader />
</div>
)}
{!loading && (
<div className={classes.contentContainer}>
<span className={classes.pieChartLabel}>
{middleLabel && splitSizeMetric(middleLabel)}
</span>
<div className={classes.chartContainer}>
<ResponsiveContainer width="99%">
<PieChart margin={{ top: 5, bottom: 5 }}>
{dataOuter && (
<Pie
data={dataOuter as object[]}
cx={"50%"}
cy={"50%"}
dataKey="value"
innerRadius={get(
pieChartConfiguration,
"outerChart.innerRadius",
0
)}
outerRadius={get(
pieChartConfiguration,
"outerChart.outerRadius",
"80%"
)}
startAngle={get(
pieChartConfiguration,
"outerChart.startAngle",
0
)}
endAngle={get(
pieChartConfiguration,
"outerChart.endAngle",
360
)}
fill="#201763"
>
{dataOuter.map((entry, index) => (
<Cell
key={`cellOuter-${index}`}
fill={
typeof outerColors[index] === "undefined"
? "#393939"
: outerColors[index]
}
/>
))}
</Pie>
)}
{dataInner && (
<Pie
data={dataInner as object[]}
dataKey="value"
cx={"50%"}
cy={"50%"}
innerRadius={get(
pieChartConfiguration,
"innerChart.innerRadius",
0
)}
outerRadius={get(
pieChartConfiguration,
"innerChart.outerRadius",
"80%"
)}
startAngle={get(
pieChartConfiguration,
"innerChart.startAngle",
0
)}
endAngle={get(
pieChartConfiguration,
"innerChart.endAngle",
360
)}
fill="#201763"
>
{dataInner.map((entry, index) => {
return (
<Cell
key={`cell-${index}`}
fill={
typeof innerColors[index] === "undefined"
? "#393939"
: innerColors[index]
}
/>
);
})}
</Pie>
)}
</PieChart>
</ResponsiveContainer>
</div>
</div>
)}
</div>
);
}
Example #13
Source File: TenantCapacity.tsx From console with GNU Affero General Public License v3.0 | 4 votes |
TenantCapacity = ({
totalCapacity,
usedSpaceVariants,
statusClass,
render = "pie",
}: ITenantCapacity) => {
const colors = [
"#8dacd3",
"#bca1ea",
"#92e8d2",
"#efc9ac",
"#97f274",
"#f7d291",
"#71ACCB",
"#f28282",
"#e28cc1",
"#2781B0",
];
const BGColor = "#ededed";
const totalUsedSpace = usedSpaceVariants.reduce((acc, currValue) => {
return acc + currValue.value;
}, 0);
const emptySpace = totalCapacity - totalUsedSpace;
let tiersList: CapacityValue[] = [];
const standardTier = usedSpaceVariants.find(
(tier) => tier.variant === "STANDARD"
) || {
value: 0,
variant: "empty",
};
if (usedSpaceVariants.length > 10) {
const totalUsedByTiers = totalUsedSpace - standardTier.value;
tiersList = [
{ value: totalUsedByTiers, color: "#2781B0", label: "Total Tiers Space" },
];
} else {
tiersList = usedSpaceVariants
.filter((variant) => variant.variant !== "STANDARD")
.map((variant, index) => {
return {
value: variant.value,
color: colors[index],
label: `Tier - ${variant.variant}`,
};
});
}
let standardTierColor = "#07193E";
const usedPercentage = (standardTier.value * 100) / totalCapacity;
if (usedPercentage >= 90) {
standardTierColor = "#C83B51";
} else if (usedPercentage >= 75) {
standardTierColor = "#FFAB0F";
}
const plotValues: CapacityValue[] = [
{
value: standardTier.value,
color: standardTierColor,
label: "Used Space by Tenant",
},
...tiersList,
{
value: emptySpace,
color: render === "bar" ? BGColor : "transparent",
label: "Empty Space",
},
];
if (render === "bar") {
const plotValuesForUsageBar: ISizeBarItem[] = plotValues.map((plotVal) => {
return {
value: plotVal.value,
color: plotVal.color,
itemName: plotVal.label,
};
});
return (
<div style={{ width: "100%", marginBottom: 15 }}>
<UsageBar
totalValue={totalCapacity}
sizeItems={plotValuesForUsageBar}
bgColor={BGColor}
/>
</div>
);
}
return (
<div style={{ position: "relative", width: 110, height: 110 }}>
<div
style={{ position: "absolute", right: -5, top: 15, zIndex: 400 }}
className={statusClass}
>
<CircleIcon
style={{
border: "#fff 2px solid",
borderRadius: "100%",
width: 20,
height: 20,
}}
/>
</div>
<span
style={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
fontWeight: "bold",
color: "#000",
fontSize: 12,
}}
>
{!isNaN(totalUsedSpace) ? niceBytesInt(totalUsedSpace) : "N/A"}
</span>
<div>
<PieChart width={110} height={110}>
<Pie
data={[{ value: 100 }]}
cx={"50%"}
cy={"50%"}
dataKey="value"
outerRadius={50}
innerRadius={40}
fill={BGColor}
isAnimationActive={false}
stroke={"none"}
/>
<Pie
data={plotValues}
cx={"50%"}
cy={"50%"}
dataKey="value"
outerRadius={50}
innerRadius={40}
>
{plotValues.map((entry, index) => (
<Cell
key={`cellCapacity-${index}`}
fill={entry.color}
stroke={"none"}
/>
))}
</Pie>
</PieChart>
</div>
</div>
);
}
Example #14
Source File: BasketStats.tsx From mStable-apps with GNU Lesser General Public License v3.0 | 4 votes |
BasketStats: FC<{ simulation?: MassetState }> = ({ simulation }) => {
const masset = useSelectedMassetState()
// eslint-disable-next-line
const bAssets: MassetState['bAssets'] = simulation?.bAssets ?? masset?.bAssets ?? {}
const data: Datum[] = useMemo(
() =>
Object.values(bAssets).map(({ basketShare, maxWeight, token: { symbol }, overweight, totalVault }) => {
const basketShareAsPercentage = basketShare.toPercent()
const maxWeightAsPercentage = new BigDecimal(maxWeight ?? '0', 18).toPercent()
// Get the remainder so that it can be stacked after the basket share
const remainderMaxWeight = parseFloat(
(basketShareAsPercentage > maxWeightAsPercentage ? 0 : maxWeightAsPercentage - basketShareAsPercentage).toFixed(2),
)
return {
symbol,
basketShareAsPercentage,
maxWeightAsPercentage,
remainderMaxWeight,
overweight,
vaultBalance: toK(totalVault.simple),
fill: overweight ? OVERWEIGHT_TOKEN_COLOURS[symbol as TokenSymbol] : TOKEN_COLOURS[symbol as TokenSymbol],
}
}),
[bAssets],
)
return (
<Container>
{data && data.length ? (
<ResponsiveContainer aspect={1.5} width={250}>
<BarChart layout="vertical" margin={{ top: 0, right: 0, bottom: 0, left: 0 }} barCategoryGap={1} data={data}>
<defs>
{Object.values(bAssets).map(b => (
<Hatch key={b.token.symbol} symbol={b.token.symbol as TokenSymbol} />
))}
</defs>
<Tooltip
cursor={false}
separator=" "
contentStyle={{
fontSize: '14px',
padding: '8px',
background: 'rgba(255, 255, 255, 0.8)',
textAlign: 'right',
border: 'none',
borderRadius: '4px',
color: Color.black,
}}
content={CustomTooltip}
wrapperStyle={{
top: 0,
left: 0,
}}
/>
<XAxis type="number" unit="%" padding={{ left: 24 }} axisLine={false} />
<YAxis
type="category"
dataKey="symbol"
tickCount={data.length}
minTickGap={0}
axisLine={false}
tick={({
payload: { value },
x,
y,
height,
}: {
payload: {
value: TokenSymbol
}
x: number
y: number
height: number
}) => {
const diameter = (height - data.length * 6) / data.length
return (
<TokenIconSvg x={x - diameter / 2} y={y - diameter / 2} height={diameter} width={diameter} symbol={value} key={value} />
) as unknown as SVGElement
}}
/>
<Bar dataKey="basketShareAsPercentage" name="Basket share" unit="%" stackId="a" />
<Bar dataKey="remainderMaxWeight" name="Max weight" unit="%" stackId="a">
{data.map(({ symbol }) => (
<Cell key={symbol} fill={`url(#hatch-${symbol})`} />
))}
</Bar>
)
</BarChart>
</ResponsiveContainer>
) : (
<ThemedSkeleton height={132} />
)}
</Container>
)
}
Example #15
Source File: index.tsx From korona-info with MIT License | 4 votes |
Index: NextPage<{ groupedCoronaData: GroupedData, hospitalised: HospitalData[] }> = ({
groupedCoronaData, hospitalised
}: {
groupedCoronaData: GroupedData;
hospitalised: HospitalData[];
}) => {
const [selectedHealthCareDistrict, selectHealthCareDistrict] = useState<
string
>('all');
const confirmed = groupedCoronaData[selectedHealthCareDistrict].confirmed;
const deaths = groupedCoronaData[selectedHealthCareDistrict].deaths;
const recovered = groupedCoronaData[selectedHealthCareDistrict].recovered;
const allConfirmed = groupedCoronaData.all.confirmed;
const toast = useToast()
const latestInfection = confirmed.length
? format(
utcToZonedTime(
new Date(confirmed[confirmed.length - 1].date),
timeZone
),
'dd.MM.yyyy - HH:mm',
{ timeZone }
)
: null;
const latestInfectionDistrict =
confirmed[confirmed.length - 1]?.healthCareDistrict;
const latestDeath = deaths.length
? format(
utcToZonedTime(new Date(deaths[deaths.length - 1].date), timeZone),
'd.M.yyyy'
)
: null;
const latestDeathDistrict = deaths.length
? deaths[deaths.length - 1].area
: null;
const latestRecoveredDistrict = recovered.length
? recovered[recovered.length - 1].healthCareDistrict
: null;
const latestRecovered = recovered.length
? format(
utcToZonedTime(
new Date(recovered[recovered.length - 1].date),
timeZone
),
'd.M.yyyy'
)
: null;
const infectionsToday = getInfectionsToday(confirmed);
const [cumulativeChartScale, setCumulativeChartScale] = useState<
'linear' | 'log'
>('linear');
const [forecastChartScale, setForecaseChartScale] = useState<
'linear' | 'log'
>('linear');
// Map data to show development of infections
const {
infectionDevelopmentData,
infectionDevelopmentData30Days
} = groupedCoronaData[selectedHealthCareDistrict].timeSeries;
const maxValues =
infectionDevelopmentData30Days[infectionDevelopmentData30Days.length - 1];
const dataMaxValue = Math.max(
maxValues?.deaths ?? 0,
maxValues?.infections ?? 0,
maxValues?.infections ?? 0
);
const {
infectionsByDistrict,
infectionsByDistrictPercentage,
areas
} = getTnfectionsByDistrict(allConfirmed);
const { infectionsBySourceCountry } = getInfectionsBySourceCountry(confirmed);
const networkGraphData = getNetworkGraphData(confirmed);
const { t } = useContext(UserContext);
const humanizeHealthcareDistrict = (district: string) => {
if (district === 'all') {
return t('All healthcare districts');
} else if (district === 'unknown') {
return t('unknown');
} else {
return district;
}
};
const reversedConfirmed = confirmed
// @ts-ignore
.map((i, index) => ({
index: index + 1,
...i,
healthCareDistrict: humanizeHealthcareDistrict(i.healthCareDistrict)
}))
.reverse();
const humanizedHealthCareDistrict = humanizeHealthcareDistrict(
selectedHealthCareDistrict
);
useEffect(() => {
if (typeof window !== undefined) {
toast({
position: 'bottom',
title: 'Datan lähteenä nyt THL',
description: 'HS:n datan lähde on vaihtunut THL:ään. THL:n tiedotussyklistä johtuen tiedot päivittyvät aiempaa harvemmin. Myös vanhemmissa tapauksissa voi olla päivämääräkohtaisia eroja, johtuen muuttuneesta raportointitavasta.',
status: "info",
isClosable: true,
duration: 14000,
});
}
}, [])
return (
<>
<Head>
<title>
{t('finland corona status')} - {t('cases')} : {confirmed.length || 0}{' '}
- {t('recovered')}: {recovered.length || 0} - {t('deaths')}:{' '}
{deaths.length || 0}
</title>
<meta
name="description"
content={`Suomen koronavirus-tartuntatilanne – tartunnat: ${confirmed.length ||
0} - parantuneet: ${recovered.length ||
0} - menehtyneet: ${deaths.length || 0}`}
/>
<meta property="og:title" content={t('finland corona status')} />
<meta
property="og:description"
content={`Tartuntoja tällä hetkellä: ${confirmed.length ||
0} - parantuneet: ${recovered.length ||
0} - menehtyneet: ${deaths.length || 0}`}
/>
<meta
property="og:site_name"
content="Suomen koronavirus-tartuntatilanne"
/>
<meta property="og:locale" content="fi_FI" />
<meta property="og:type" content="website" />
<meta property="og:image" content="/images/corona-virus.png" />
<meta property="og:image:width" content="1920" />
<meta property="og:image:height" content="1928" />
<meta property="og:url" content="https://korona.kans.io" />
</Head>
<Layout>
<Flex
alignItems="center"
flexDirection="column"
flex="1"
width={'100%'}
maxWidth="1440px"
margin="auto"
>
<Header />
<Flex
flexWrap="wrap"
flexDirection="row"
justifyContent="left"
alignItems="stretch"
flex="1"
width={'100%'}
>
<Box width={['100%', '100%', 1 / 3, 1 / 3]} p={3}>
<Select
value={selectedHealthCareDistrict ?? undefined}
onChange={event => selectHealthCareDistrict(event.target.value)}
>
<option key={'all'} value={'all'}>
{t('All healthcare districts')}
</option>
{healtCareDistricts.map(healthcareDistrict => (
<option
key={healthcareDistrict.name}
value={healthcareDistrict.name}
>
{healthcareDistrict.name}
</option>
))}
))}
</Select>
</Box>
</Flex>
<Flex
flexWrap="wrap"
flexDirection="row"
justifyContent="center"
alignItems="stretch"
flex="1"
width={'100%'}
>
<Box width={['100%', '100%', 1 / 2, 1 / 2]} p={3}>
<Block
title={t('cases') + ` (${humanizedHealthCareDistrict})`}
textAlign="center"
extraInfo={`${t('New cases today')} ${infectionsToday} ${t(
'person'
)}`}
footer={`${t(
'latest case'
)} ${latestInfection} (${humanizeHealthcareDistrict(
latestInfectionDistrict
)})`}
>
<StatBlock
count={confirmed.length}
helpText={`${t('New cases today')}: ${infectionsToday} ${t(
'person'
)}`}
/>
</Block>
</Box>
<Box width={['100%', '100%', 1 / 2, 1 / 2]} p={3}>
<Block
title={t('deaths') + ` (${humanizedHealthCareDistrict})`}
footer={
latestDeath
? `${t(
'last death'
)} ${latestDeath} (${humanizeHealthcareDistrict(
latestDeathDistrict!
)})`
: t('no death')
}
>
<StatBlock count={deaths.length || 0} />
</Block>
</Box>
{/* <Box width={['100%', '100%', 1 / 3, 1 / 3]} p={3}>
<Block
title={t('recovered') + ` (${humanizedHealthCareDistrict})`}
footer={
`${latestRecovered
? `${t(
'latest recovery'
)} ${latestRecovered} (${humanizeHealthcareDistrict(latestRecoveredDistrict!)}).`
: ' '} ${t('recoveredNotice')}`}
>
<StatBlock count={recovered.length || 0} />
</Block>
</Box> */}
<Box width={['100%']} p={3}>
<Block
title={
t('accumulated change') + ` (${humanizedHealthCareDistrict})`
}
footer={t('cases recovered and death in past 30 days')}
>
<ButtonGroup
spacing={0}
alignSelf="center"
display="flex"
justifyContent="center"
marginTop="-15px"
>
<Button
size="xs"
fontFamily="Space Grotesk Regular"
px={3}
letterSpacing="1px"
borderRadius="4px 0px 0px 4px"
borderWidth="0px"
isActive={cumulativeChartScale === 'linear'}
onClick={() => setCumulativeChartScale('linear')}
>
{t('linear')}
</Button>
<Button
size="xs"
fontFamily="Space Grotesk Regular"
px={3}
letterSpacing="1px"
borderRadius="0px 4px 4px 0px"
borderWidth="0px"
isActive={cumulativeChartScale === 'log'}
onClick={() => setCumulativeChartScale('log')}
>
{t('logarithmic')}
</Button>
</ButtonGroup>
<ResponsiveContainer width={'100%'} height={380}>
<ComposedChart
data={
cumulativeChartScale === 'log'
? infectionDevelopmentData30Days.map(zerosToNulls)
: infectionDevelopmentData30Days
}
margin={{ top: 20, right: 30, left: 0, bottom: 30 }}
>
<defs>
<linearGradient
id="colorInfection"
x1="0"
y1="0"
x2="0"
y2="1"
>
<stop
offset="5%"
stopColor={colors[8]}
stopOpacity={0.6}
/>
<stop
offset="95%"
stopColor={colors[8]}
stopOpacity={0}
/>
</linearGradient>
<linearGradient
id="colorRecovered"
x1="0"
y1="0"
x2="0"
y2="1"
>
<stop
offset="5%"
stopColor={colors[7]}
stopOpacity={0.6}
/>
<stop
offset="95%"
stopColor={colors[7]}
stopOpacity={0}
/>
</linearGradient>
<linearGradient
id="colorDeaths"
x1="0"
y1="0"
x2="0"
y2="1"
>
<stop
offset="5%"
stopColor={colors[0]}
stopOpacity={0.6}
/>
<stop
offset="95%"
stopColor={colors[0]}
stopOpacity={0}
/>
</linearGradient>
</defs>
<XAxis
tickFormatter={d => format(new Date(d), 'd.M.')}
tick={<CustomizedAxisTick isDate />}
dataKey="date"
domain={['dataMin', 'dataMax']}
type="number"
scale="time"
/>
<YAxis
scale={cumulativeChartScale}
dataKey="infections"
domain={[
cumulativeChartScale === 'log' ? 1 : 0,
dataMaxValue + 10
]}
unit={' ' + t('person')}
tick={{ fontSize: 12 }}
name={t('cases')}
/>
<CartesianGrid opacity={0.2} />
<Tooltip
labelFormatter={v => format(new Date(v), 'dd.MM.yyyy')}
/>
<Bar
isAnimationActive={false}
fill={colors[1]}
opacity={0.4}
dataKey="infectionsDaily"
name={t('cases of the day')}
unit={' ' + t('person')}
/>
<Area
isAnimationActive={false}
type="monotone"
unit={' ' + t('person')}
name={t('total cases')}
dataKey="infections"
stroke={colors[8]}
fillOpacity={1}
fill="url(#colorInfection)"
/>
{/* <Area
isAnimationActive={false}
type="monotone"
unit={' ' + t('person')}
name={t('total recovered')}
dataKey="recovered"
stroke={colors[7]}
fillOpacity={1}
fill="url(#colorRecovered)"
/> */}
<Area
isAnimationActive={false}
type="monotone"
unit={' ' + t('person')}
name={t('total deaths')}
dataKey="deaths"
stroke={colors[0]}
fillOpacity={1}
fill="url(#colorDeaths)"
/>
<Legend wrapperStyle={{ bottom: '10px' }} />
</ComposedChart>
</ResponsiveContainer>
</Block>
</Box>
{/*
<Box width={['100%']} p={3}>
<Block title="Tartuntojen kumulatiivinen ennustemalli" footer={`Tartuntojen kehityksen ennustemalli 60 päivää. Laskee ennustetun eksponentiaalisen kasvun käyttämällä aiemmin luotuja tietoja. Käytetty <a style="color: #319795;" href="https://github.com/mljs/regression-exponential" target="_blank">exponential-regression</a> kirjastoa.`}>
<ButtonGroup spacing={0} alignSelf="center" display="flex" justifyContent="center" marginTop="-15px">
<Button size="xs" fontFamily="Space Grotesk Regular" px={3} letterSpacing="1px" borderRadius="4px 0px 0px 4px" borderWidth="0px" isActive={forecastChartScale === 'linear'} onClick={() => setForecaseChartScale('linear')}>
Lineaarinen
</Button>
<Button size="xs" fontFamily="Space Grotesk Regular" px={3} letterSpacing="1px" borderRadius="0px 4px 4px 0px" borderWidth="0px" isActive={forecastChartScale === 'log'} onClick={() => setForecaseChartScale('log')}>
Logaritminen
</Button>
</ButtonGroup>
<ResponsiveContainer width={'100%'} height={350}>
<AreaChart
data={prediction60Days}
margin={{ top: 20, right: 30, left: 0, bottom: 20 }}
>
<defs>
<linearGradient id="colorInfection" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor={colors[8]} stopOpacity={0.6} />
<stop offset="95%" stopColor={colors[8]} stopOpacity={0} />
</linearGradient>
</defs>
<XAxis tickFormatter={d => format(new Date(d), 'd.M.')} tick={<CustomizedAxisTick isDate />} dataKey="date" domain={['dataMin', 'dataMax']} type="number" scale="time" />
<YAxis scale={forecastChartScale} dataKey="infections" domain={['auto', 'auto']} unit={' ' + t('person') } tick={{ fontSize: 12 }} name="Tartunnat" />
<CartesianGrid opacity={0.2} />
<ReferenceLine
x={today}
stroke="rgba(0,0,0,.5)"
// @ts-ignore
label={{ position: 'top', value: 'Nyt', fill: 'rgba(0,0,0,0.5)', fontSize: 12 }}
strokeDasharray="3 3" />
<Tooltip labelFormatter={v => format(new Date(v), 'dd.MM.yyyy')} />
<Area type="monotone" name="Ennuste" unit={' ' + t('person') } dataKey="infections" stroke={colors[8]} fillOpacity={1} fill="url(#colorInfection)" />
</AreaChart>
</ResponsiveContainer>
</Block>
</Box>
*/}
<Box width={['100%', '100%', '100%', '100%', 1 / 2]} p={3}>
<Block
title={t('Cases by district')}
footer={t('Helsinki metropolitan area is shown as HUS')}
>
<ResponsiveContainer width={'100%'} height={350}>
<BarChart
data={infectionsByDistrict}
margin={{
top: 20,
right: 30,
left: 0,
bottom: 85
}}
>
<XAxis
interval={0}
dataKey="name"
tick={<CustomizedAxisTick />}
/>
<YAxis
yAxisId="left"
unit={' ' + t('person')}
dataKey="infections"
tick={{ fontSize: 12 }}
/>
<Tooltip />
<Bar
isAnimationActive={false}
dataKey="infections"
name={t('cases')}
unit={' ' + t('person')}
yAxisId="left"
>
{areas.map((area, index) => (
<Cell key={area} fill={colors[index % colors.length]} />
))}
<LabelList
dataKey="infections"
position="top"
formatter={e => e}
/>
</Bar>
</BarChart>
</ResponsiveContainer>
</Block>
</Box>
<Box width={['100%', '100%', '100%', '100%', 1 / 2]} p={3}>
<Block
title={t('infectionsPerDisrictAndSize')}
footer={t('infectionsPerDisrictAndSize')}
>
<ResponsiveContainer width={'100%'} height={350}>
<BarChart
data={infectionsByDistrictPercentage}
margin={{
top: 20,
right: 30,
left: 0,
bottom: 85
}}
>
<XAxis
interval={0}
dataKey="name"
tick={<CustomizedAxisTick />}
/>
<YAxis
unit=" %"
dataKey="perDistrict"
tick={{ fontSize: 12 }}
/>
<Tooltip />
<Bar isAnimationActive={false} dataKey="perDistrict" name="%-osuus väestöstä" unit=" %">
{areas.map((area, index) => (
<Cell key={area} fill={colors[index % colors.length]} />
))}
<LabelList
dataKey="perDistict"
position="top"
formatter={e => e}
/>
</Bar>
</BarChart>
</ResponsiveContainer>
</Block>
</Box>
<Box width={['100%', '100%', '100%', '100%', 1 / 2]} p={3}>
<Block
title={t('log') + ` (${humanizedHealthCareDistrict})`}
footer={t('logFooter')}
>
<Table
height={500}
data={reversedConfirmed}
columns={useMemo(() => infectionColumns, [])}
/>
</Block>
</Box>
<BubbleChart data={groupedCoronaData} />
{/* <Box width={['100%', '100%', '100%', '100%', 1 / 2]} p={3}>
<Block
title={
t('infectionNetwork') + ` (${humanizedHealthCareDistrict})`
}
footer={t('infectionNetworkFooter')}
>
<NetworkGraph data={networkGraphData} />
</Block>
</Box> */}
<Box width={['100%']} p={3}>
<Block
title={
t('hospitalizedData') + ` (${t('All healthcare districts')})`
}
>
<ResponsiveContainer width={'100%'} height={350}>
<BarChart
data={hospitalised.slice(Math.max(hospitalised.length - 30, 0))}
margin={{
top: 20,
right: 30,
left: 0,
bottom: 85
}}
>
<XAxis
interval={0}
dataKey="dateString"
tick={<CustomizedAxisTick />}
padding={{ left: 50, right: 50 }}
/>
<YAxis
unit={' ' + t('person')}
dataKey="totalHospitalised"
tick={{ fontSize: 12 }}
/>
<Tooltip />
<Bar
isAnimationActive={false}
stackId="a"
dataKey="inIcu"
name={t("inIcu")}
unit={' ' + t('person')}
fill="#F3858D"
/>
<Bar
isAnimationActive={false}
stackId="a"
dataKey="inWard"
name={t("inWard")}
unit={' ' + t('person')}
fill="#2FAB8E"
/>
<Bar
isAnimationActive={false}
stackId="a"
dataKey="totalHospitalised"
opacity={0}
name={t("inHospital")}
unit={' ' + t('person')}
fill="rgba(0,0,0,1)"
strokeWidth={0}
legendType="none"
/>
<Legend wrapperStyle={{ bottom: '15px' }} />
</BarChart>
</ResponsiveContainer>
</Block>
</Box>
</Flex>
<Copyright />
</Flex>
</Layout>
</>
);
}