feat: add map chart
This commit is contained in:
parent
855136eb9a
commit
4079d64276
|
@ -0,0 +1,86 @@
|
|||
import styled from "styled-components";
|
||||
import React from "react";
|
||||
// import { VectorMap } from "@south-paw/react-vector-maps";
|
||||
|
||||
import { Colors } from "../../consts";
|
||||
import Tooltip from "../Tooltip";
|
||||
import world from "./world.json";
|
||||
|
||||
const Svg = styled.svg`
|
||||
path {
|
||||
fill: ${Colors.Map0};
|
||||
stroke: #fff;
|
||||
}
|
||||
|
||||
path.country-6 {
|
||||
fill: ${Colors.Map06};
|
||||
stroke: #fff;
|
||||
}
|
||||
path.country-5 {
|
||||
fill: ${Colors.Map05};
|
||||
stroke: #fff;
|
||||
}
|
||||
path.country-4 {
|
||||
fill: ${Colors.Map04};
|
||||
stroke: #fff;
|
||||
}
|
||||
path.country-3 {
|
||||
fill: ${Colors.Map03};
|
||||
stroke: #fff;
|
||||
}
|
||||
path.country-2 {
|
||||
fill: ${Colors.Map02};
|
||||
stroke: #fff;
|
||||
}
|
||||
path.country-1 {
|
||||
fill: ${Colors.Map01};
|
||||
stroke: #fff;
|
||||
}
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
data: Array<{ name: string; value: number }>;
|
||||
}
|
||||
|
||||
const Map = ({ data }) => {
|
||||
const [mostVisits] = data.sort((a, b) => (a > b ? 1 : -1));
|
||||
return (
|
||||
<>
|
||||
{world.layers.map(layer => (
|
||||
<>
|
||||
<Tooltip
|
||||
type="light"
|
||||
effect="float"
|
||||
id={`${layer.id}-tooltip-country`}
|
||||
>
|
||||
{layer.name}:{" "}
|
||||
{data.find(d => d.name.toLowerCase() === layer.id)?.value || 0}
|
||||
</Tooltip>
|
||||
</>
|
||||
))}
|
||||
<Svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-label="world map"
|
||||
viewBox={world.viewBox}
|
||||
>
|
||||
{world.layers.map(layer => (
|
||||
<>
|
||||
<path
|
||||
data-tip
|
||||
data-for={`${layer.id}-tooltip-country`}
|
||||
className={`country-${Math.ceil(
|
||||
((data.find(d => d.name.toLowerCase() === layer.id)?.value ||
|
||||
0) / mostVisits?.value || 0) * 6
|
||||
)}`}
|
||||
key={layer.id}
|
||||
aria-label={layer.name}
|
||||
d={layer.d}
|
||||
/>
|
||||
</>
|
||||
))}
|
||||
</Svg>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Map;
|
|
@ -1,3 +1,4 @@
|
|||
export { default as Area } from "./Area";
|
||||
export { default as Bar } from "./Bar";
|
||||
export { default as Pie } from "./Pie";
|
||||
export { default as Map } from "./Map";
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,12 +1,14 @@
|
|||
import ReactTooltip from "react-tooltip";
|
||||
import styled from "styled-components";
|
||||
|
||||
const Tooltip = styled(ReactTooltip).attrs({
|
||||
effect: "solid"
|
||||
})`
|
||||
const Tooltip = styled(ReactTooltip)`
|
||||
padding: 3px 7px;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
`;
|
||||
|
||||
Tooltip.defaultProps = {
|
||||
effect: "solid"
|
||||
};
|
||||
|
||||
export default Tooltip;
|
||||
|
|
|
@ -16,32 +16,39 @@ export enum APIv2 {
|
|||
}
|
||||
|
||||
export enum Colors {
|
||||
Text = "hsl(200, 35%, 25%)",
|
||||
Bg = "hsl(206, 12%, 95%)",
|
||||
Spinner = "hsl(200, 15%, 70%)",
|
||||
FeaturesBg = "hsl(230, 15%, 92%)",
|
||||
ExtensionsBg = "hsl(230, 15%, 20%)",
|
||||
Icon = "hsl(200, 35%, 45%)",
|
||||
IconShadow = "hsla(200, 15%, 60%, 0.12)",
|
||||
CheckIcon = "hsl(144, 50%, 60%)",
|
||||
CopyIcon = "hsl(144, 40%, 57%)",
|
||||
CopyIconBg = "hsl(144, 100%, 96%)",
|
||||
CheckIcon = "hsl(144, 50%, 60%)",
|
||||
TrashIcon = "hsl(0, 100%, 69%)",
|
||||
TrashIconBg = "hsl(0, 100%, 96%)",
|
||||
StopIcon = "hsl(10, 100%, 40%)",
|
||||
StopIconBg = "hsl(10, 100%, 96%)",
|
||||
QrCodeIcon = "hsl(0, 0%, 35%)",
|
||||
QrCodeIconBg = "hsl(0, 0%, 94%)",
|
||||
Divider = "hsl(200, 20%, 92%)",
|
||||
EditIcon = "hsl(46, 90%, 50%)",
|
||||
EditIconBg = "hsl(46, 100%, 94%)",
|
||||
ExtensionsBg = "hsl(230, 15%, 20%)",
|
||||
FeaturesBg = "hsl(230, 15%, 92%)",
|
||||
Icon = "hsl(200, 35%, 45%)",
|
||||
IconShadow = "hsla(200, 15%, 60%, 0.12)",
|
||||
Map0 = "hsl(200, 15%, 92%)",
|
||||
Map06 = "hsl(261, 46%, 68%)",
|
||||
Map05 = "hsl(261, 46%, 72%)",
|
||||
Map04 = "hsl(261, 46%, 76%)",
|
||||
Map03 = "hsl(261, 46%, 82%)",
|
||||
Map02 = "hsl(261, 46%, 86%)",
|
||||
Map01 = "hsl(261, 46%, 90%)",
|
||||
PieIcon = "hsl(260, 100%, 69%)",
|
||||
PieIconBg = "hsl(260, 100%, 96%)",
|
||||
TableHeadBg = "hsl(200, 12%, 95%)",
|
||||
TableHeadBorder = "hsl(200, 14%, 94%)",
|
||||
TableBorder = "hsl(200, 14%, 90%)",
|
||||
TableRowHover = "hsl(200, 14%, 98%)",
|
||||
TableShadow = "hsla(200, 20%, 70%, 0.3)",
|
||||
QrCodeIcon = "hsl(0, 0%, 35%)",
|
||||
QrCodeIconBg = "hsl(0, 0%, 94%)",
|
||||
Spinner = "hsl(200, 15%, 70%)",
|
||||
StatsLastUpdateText = "hsl(200, 14%, 60%)",
|
||||
StatsTotalUnderline = "hsl(200, 35%, 65%)",
|
||||
Divider = "hsl(200, 20%, 92%)"
|
||||
StopIcon = "hsl(10, 100%, 40%)",
|
||||
StopIconBg = "hsl(10, 100%, 96%)",
|
||||
TableBorder = "hsl(200, 14%, 90%)",
|
||||
TableHeadBg = "hsl(200, 12%, 95%)",
|
||||
TableHeadBorder = "hsl(200, 14%, 94%)",
|
||||
TableRowHover = "hsl(200, 14%, 98%)",
|
||||
TableShadow = "hsla(200, 20%, 70%, 0.3)",
|
||||
Text = "hsl(200, 35%, 25%)",
|
||||
TrashIcon = "hsl(0, 100%, 69%)",
|
||||
TrashIconBg = "hsl(0, 100%, 96%)"
|
||||
}
|
||||
|
|
|
@ -9,13 +9,13 @@ import Text, { H1, H2, H4, Span } from "../components/Text";
|
|||
import { getAxiosConfig, removeProtocol } from "../utils";
|
||||
import { Button, NavButton } from "../components/Button";
|
||||
import { Col, RowCenterV } from "../components/Layout";
|
||||
import { Area, Bar, Pie } from "../components/Charts";
|
||||
import { Area, Bar, Pie, Map } from "../components/Charts";
|
||||
import PageLoading from "../components/PageLoading";
|
||||
import AppWrapper from "../components/AppWrapper";
|
||||
import Divider from "../components/Divider";
|
||||
import { APIv2, Colors } from "../consts";
|
||||
import { useStoreState } from "../store";
|
||||
import ALink from "../components/ALink";
|
||||
import { APIv2, Colors } from "../consts";
|
||||
import Icon from "../components/Icon";
|
||||
|
||||
interface Props {
|
||||
|
@ -173,7 +173,7 @@ const StatsPage: NextPage<Props> = ({ id }) => {
|
|||
<H2 mb={3} light>
|
||||
Country.
|
||||
</H2>
|
||||
<Pie data={stats.stats.country} />
|
||||
<Map data={stats.stats.country} />
|
||||
</Col>
|
||||
<Col flex="1 1 0">
|
||||
<H2 mb={3} light>
|
||||
|
|
Loading…
Reference in New Issue