Skip to content

Commit

Permalink
Merge pull request #13 from NewWays-TechForImpactKAIST/feat/map-selector
Browse files Browse the repository at this point in the history
Feat/map selector
  • Loading branch information
songc04 authored Nov 17, 2023
2 parents 3c488bc + 40407c1 commit 9538178
Show file tree
Hide file tree
Showing 11 changed files with 2,136 additions and 42 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ dist/
# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# IntelliJ
.idea/

# Temporary folders
tmp/
temp/
Expand Down
70 changes: 70 additions & 0 deletions src/components/organisms/LocalSelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { MapSVG, type MetroID, MetroInfo } from "@/../static/MapSVGData";
import { type ReactNode } from "react";

interface Props {
selected: MetroID;
onClick?: (local: string) => void;
}

const LocalSelector = ({ selected, onClick = () => {} }: Props) => (
<svg
version="1.1"
id="Layer_1"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
viewBox={MetroInfo[selected]?.viewBox || "0 0 509 716.1"}
xmlSpace="preserve"
>
<style type="text/css">
{`
.local{
fill: ${MetroInfo[selected]?.color || "#1c3f64"};
stroke: #1c3f64;
stroke-width: 0.5px;
-webkit-transition:
fill 0.2s,
stroke 0.2s
}
.local:hover{
fill: #1c3f64;
}
`}
</style>
{MapSVG.map<ReactNode>(group =>
group.groupId === selected ? (
<g key={group.groupId}>
{group.component.map(shape => {
if (shape.type === `path`) {
return (
<path
key={shape.id}
className="local"
id={shape.id}
d={shape.data}
onClick={() => onClick(shape.id)}
/>
);
}
if (shape.type === `polygon`) {
return (
<polygon
key={shape.id}
className="local"
id={shape.id}
points={shape.data}
onClick={() => onClick(shape.id)}
/>
);
}
throw new Error(`${shape.id} is not path or polygon`);
})}
</g>
) : (
<g key={group.groupId} />
),
)}
</svg>
);
export default LocalSelector;
72 changes: 72 additions & 0 deletions src/components/organisms/MetroSelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { MapSVG, MetroInfo } from "@/../static/MapSVGData";
import { type ReactNode, useState } from "react";

interface Props {
onClick?: (local: string) => void;
}

const MetroSelector = ({ onClick = () => {} }: Props) => {
const [hover, setHover] = useState<string>("");
return (
<svg
version="1.1"
id="Layer_1"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
viewBox="0 0 509 716.1"
xmlSpace="preserve"
>
<style type="text/css">
{`
.metro{
-webkit-transition:
fill 0.2s,
stroke 0.2s
}
`}
</style>
{MapSVG.map<ReactNode>(group => (
<g
key={group.groupId}
id={group.groupId}
className="metro"
style={{
fill:
hover !== group.groupId
? MetroInfo[group.groupId].color
: "#1c3f64",
stroke:
hover !== group.groupId
? MetroInfo[group.groupId].color
: "#1c3f64",
}}
onMouseEnter={() => {
setHover(group.groupId);
}}
onMouseLeave={() => {
setHover("");
}}
onClick={() => {
onClick(group.groupId);
}}
>
{group.component.map(shape => {
if (shape.type === `path`) {
return <path key={shape.id} id={shape.id} d={shape.data} />;
}
if (shape.type === `polygon`) {
return (
<polygon key={shape.id} id={shape.id} points={shape.data} />
);
}
throw new Error(`${shape.id} is not path or polygon`);
})}
</g>
))}
</svg>
);
};

export default MetroSelector;
6 changes: 4 additions & 2 deletions src/components/organisms/PieChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@ export interface PieChartData {

export interface Props {
data: PieChartData[];
colors: string[];
}

const PieChart = ({ data }: Props) => {
const PieChart = ({ data, colors }: Props) => {
const config: PieConfig = {
appendPadding: 10,
data,
angleField: "value",
colorField: "type",
radius: 0.6,
label: {
type: "outer",
content: "{name} {percentage}",
},
colorField: "type",
color: colors,
interactions: [
{
type: "pie-legend-active",
Expand Down
2 changes: 2 additions & 0 deletions src/components/organisms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export { default as Footer } from "./Footer";
export { default as Histogram } from "./Histogram";
export { default as PieChart } from "./PieChart";
export { default as TestChart } from "./TestChart";
export { default as MetroSelector } from "./MetroSelector";
export { default as LocalSelector } from "./LocalSelector";
32 changes: 32 additions & 0 deletions src/components/pages/LocalCouncil.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from "react";
import { Flex } from "antd";
import { css } from "@emotion/react";

import { Layout } from "@/components/templates";
import { LocalSelector, MetroSelector } from "@/components/organisms";

const LocalCouncil: React.FC = () => (
<Layout>
<Flex
vertical
gap={40}
css={css`
margin: 40px 0 40px 0;
`}
>
<LocalSelector
selected="서울특별시"
onClick={id => {
alert(id);

Check warning on line 20 in src/components/pages/LocalCouncil.tsx

View workflow job for this annotation

GitHub Actions / Lint and Format (18.x)

Unexpected alert
}}
/>
<MetroSelector
onClick={id => {
alert(id);

Check warning on line 25 in src/components/pages/LocalCouncil.tsx

View workflow job for this annotation

GitHub Actions / Lint and Format (18.x)

Unexpected alert
}}
/>
</Flex>
</Layout>
);

export default LocalCouncil;
53 changes: 35 additions & 18 deletions src/components/pages/LocalCouncilReport.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,47 @@
import React from "react";
import { Flex } from "antd";
import { Flex, Typography } from "antd";
import { css } from "@emotion/react";
import { useParams } from "react-router-dom";

import { Layout } from "@/components/templates";
import { Histogram, PieChart } from "@/components/organisms";

import {
sampleAgeHistogramData,
samplePartyPieData,
sampleSexPieData,
} from "@/utils";

const Test: React.FC = () => (
<Layout>
<Flex
vertical
gap={40}
css={css`
margin: 40px 0 40px 0;
`}
>
<Histogram data={sampleAgeHistogramData} />
<PieChart data={samplePartyPieData} />
<PieChart data={sampleSexPieData} />
</Flex>
</Layout>
);
const { Title } = Typography;

const LocalCouncilReport: React.FC = () => {
const { metroId, localId } = useParams();
return (
<Layout>
<Flex
vertical
gap={40}
css={css`
margin: 40px 0 40px 0;
`}
>
<Title
level={1}
>{`MetroId(${metroId}) LocalId(${localId})의 지역의회 다양성 리포트`}</Title>
<Title level={2}>연령 다양성</Title>
<Histogram data={sampleAgeHistogramData} />
<Title level={2}>정당 다양성</Title>
<PieChart
data={samplePartyPieData.data}
colors={samplePartyPieData.colors}
/>
<Title level={2}>성별 다양성</Title>
<PieChart
data={sampleSexPieData.data}
colors={sampleSexPieData.colors}
/>
</Flex>
</Layout>
);
};

export default Test;
export default LocalCouncilReport;
1 change: 1 addition & 0 deletions src/components/pages/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
// page 컴포넌트를 모아놓은 파일
export { default as LocalCouncil } from "./LocalCouncil";
export { default as LocalCouncilReport } from "./LocalCouncilReport";
10 changes: 8 additions & 2 deletions src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ import {
createBrowserRouter,
createRoutesFromElements,
Route,
Navigate,
} from "react-router-dom";
import { LocalCouncilReport } from "@/components/pages";
import { LocalCouncil, LocalCouncilReport } from "@/components/pages";

const router = createBrowserRouter(
createRoutesFromElements([
<Route path="/" element={<LocalCouncilReport />} />,
<Route path="/localCouncil" element={<LocalCouncil />} />,
<Route
path="/localCouncilReport/:metroId/:localId"
element={<LocalCouncilReport />}
/>,
<Route path="*" element={<Navigate to="/localCouncil" />} />,
]),
);

Expand Down
46 changes: 26 additions & 20 deletions src/utils/sampleData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,30 @@ export const sampleAgeHistogramData = [
},
];

export const samplePartyPieData = [
{
type: "국민의힘",
value: 7,
},
{
type: "더불어민주당",
value: 5,
},
];
export const samplePartyPieData = {
colors: ["#E61E2B", "#00A0E2"],
data: [
{
type: "국민의힘",
value: 7,
},
{
type: "더불어민주당",
value: 5,
},
],
};

export const sampleSexPieData = [
{
type: "남성",
value: 7,
},
{
type: "여성",
value: 5,
},
];
export const sampleSexPieData = {
colors: ["#FF0000", "#0000FF"],
data: [
{
type: "남성",
value: 7,
},
{
type: "여성",
value: 5,
},
],
};
Loading

0 comments on commit 9538178

Please sign in to comment.