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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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>
    </>
  );
}