Skip to content

Commit

Permalink
finished new dashboard design
Browse files Browse the repository at this point in the history
  • Loading branch information
Nawafds committed Dec 4, 2023
1 parent 7a83a28 commit 6a19989
Show file tree
Hide file tree
Showing 11 changed files with 509 additions and 388 deletions.
7 changes: 4 additions & 3 deletions backend/dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ const connectWithMongoDB = async (mongo_url, db_name) => {
// Build things you need inside to pass to context
const contextWrapper = async () => {
// Context Metadata
const mongo_url = process.env.NAACP_MONGODB || "mongodb://mongo:[email protected]:8024"; // Local development
// const mongo_url = process.env.NAACP_MONGODB;
const dbName = "se_naacp_db";
const mongo_url = process.env.NAACP_MONGODB || "mongodb://localhost:27017";
// const mongo_url = "mongodb://localhost:27017";
// const dbName = "se_naacp_db";
const dbName = "se_naacp_gbh";
return { db: await connectWithMongoDB(mongo_url, dbName) };
};
const { url } = await startStandaloneServer(server, {
Expand Down
10 changes: 4 additions & 6 deletions backend/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,10 @@ const connectWithMongoDB = async (
const contextWrapper: ContextWrapperFunction = async () => {
// Context Metadata

const mongo_url = process.env.NAACP_MONGODB || "mongodb+srv://naacpUser:[email protected]/"; // Local development

// const mongo_url = process.env.NAACP_MONGODB || "mongodb://mongo:[email protected]:8024"; // Local development
// const mongo_url = process.env.NAACP_MONGODB;
const dbName = "se_naacp_db";
// const dbName = "se_naacp_gbh";
const mongo_url = process.env.NAACP_MONGODB || "mongodb://localhost:27017";
// const mongo_url = "mongodb://localhost:27017";
// const dbName = "se_naacp_db";
const dbName = "se_naacp_gbh";

return { db: await connectWithMongoDB(mongo_url, dbName) };
};
Expand Down
22 changes: 22 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@
"pigeon-maps": "^0.21.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.12.0",
"react-konva": "^18.2.10",
"react-lottie-player": "^1.5.4",
"react-redux": "^8.0.5",
"react-router-dom": "^6.8.0",
"react-scripts": "^5.0.1",
"react-tabs": "^6.0.2",
"react-tooltip": "^5.10.0",
"redux-logger": "^3.0.6",
"typescript": "^4.9.5",
Expand Down
128 changes: 66 additions & 62 deletions frontend/src/components/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import { ArticleContext } from "../../contexts/article_context";
import { Article } from "../../__generated__/graphql";
import Callback from "../../pages/Callback/Callback";
import { NeighborhoodContext } from "../../contexts/neighborhood_context";
import "./Accordion.css"
import "./Accordion.css";
import BubbleChart from "../BubbleChart/BubbleChart";
interface TractCount {
tract: string;
count: number;
name: string;
value: number;
}

interface LabelDetail {
Expand All @@ -22,8 +23,8 @@ interface LabelDetail {
}

interface LabelCount {
label: string;
count: number;
name: string;
value: number;
}

interface TractDetail {
Expand All @@ -44,44 +45,42 @@ function getNeighborhood(
return "";
}

const getLabelDetailsWithLimitedTracts = (
articles: Article[],
neighborhoods: { [key: string]: string[] }
): React.ReactElement<any, any> => {
const getLabelDetailsWithLimitedTracts = (articles: Article[], neighborhoods: { [key: string]: string[] }): React.ReactElement<any, any> => {
const labelDetails: Record<
string,
{ totalCount: number; tracts: Record<string, number> }
{ totalCount: number; tracts: Record<string, { count: number, articles: Article[] }> }
> = {};

// Counting labels and tracts
// Counting labels, tracts, and storing articles for each tract
articles.forEach((article) => {
const countedLabels: Set<string> = new Set();

article.openai_labels.forEach((label) => {
if (!countedLabels.has(label)) {
if (!labelDetails[label]) {
labelDetails[label] = { totalCount: 0, tracts: {} };
}
labelDetails[label].totalCount =
labelDetails[label].totalCount + article.tracts.length;
countedLabels.add(label);
if (!labelDetails[label]) {
labelDetails[label] = { totalCount: 0, tracts: {} };
}
labelDetails[label].totalCount += article.tracts.length;

article.tracts.forEach((tract) => {
labelDetails[label].tracts[tract] =
(labelDetails[label].tracts[tract] || 0) + 1;
if (!labelDetails[label].tracts[tract]) {
labelDetails[label].tracts[tract] = { count: 0, articles: [] };
}
labelDetails[label].tracts[tract].count++;
labelDetails[label].tracts[tract].articles.push(article);
});
});
});

// Converting to desired structure with sorting and limiting tracts
// Transforming to the desired structure
const labelDetailsArray: LabelDetail[] = Object.entries(labelDetails).map(
([label, detail]) => ({
label: label,
totalCount: detail.totalCount,
tractsCount: Object.entries(detail.tracts)
.map(([tract, count]) => ({ tract, count }))
.sort((a, b) => b.count - a.count)
.map(([name, tractDetail]) => ({
name,
value: tractDetail.count,
articles: tractDetail.articles
}))
.sort((a, b) => b.value - a.value)
.slice(0, 5), // Limit to first 5 tracts
})
);
Expand All @@ -91,6 +90,8 @@ const getLabelDetailsWithLimitedTracts = (
.sort((a, b) => b.totalCount - a.totalCount)
.slice(0, 5); // Limit to top 5 labels

console.log(result);

return (
<>
<div>
Expand All @@ -104,13 +105,8 @@ const getLabelDetailsWithLimitedTracts = (
<Typography color="common.black">{`${label.label} - ${label.totalCount} articles`}</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography color="common.black">
{label.tractsCount.map((tract) => (
<li key={tract.tract}>
{`${tract.tract} - ${getNeighborhood(tract.tract, neighborhoods)} - ${tract.count} articles`}
</li>
))}
</Typography>

<BubbleChart bubbleData={label.tractsCount}></BubbleChart>
</AccordionDetails>
</Accordion>
))}
Expand All @@ -119,63 +115,72 @@ const getLabelDetailsWithLimitedTracts = (
);
};


const getTractDetailsWithTotalCount = (
articles: Article[],
neighborhoods: { [key: string]: string[] }
): React.ReactElement<any, any> => {
const tractDetails: Record<
string,
{ totalLabelCount: number; labels: Record<string, number> }
{ totalLabelCount: number; labels: Record<string, { count: number, articles: Article[] }> }
> = {};

// Counting tracts and labels within each tract
// Counting tracts, labels within each tract, and storing articles
articles.forEach((article) => {
article.tracts.forEach((tract) => {
if (!tractDetails[tract]) {
tractDetails[tract] = { totalLabelCount: 0, labels: {} };
}

article.openai_labels.forEach((label) => {
tractDetails[tract].labels[label] =
(tractDetails[tract].labels[label] || 0) + 1;
tractDetails[tract].totalLabelCount++;
if (!tractDetails[tract].labels[label]) {
tractDetails[tract].labels[label] = { count: 0, articles: [] };
}
tractDetails[tract].labels[label].count++;
tractDetails[tract].labels[label].articles.push(article);
});

tractDetails[tract].totalLabelCount++;
});
});

// Converting to desired structure and slicing top 5 tracts
// Converting to desired structure
const tractDetailsArray: TractDetail[] = Object.entries(tractDetails)
.map(([tract, detail]) => ({
tract: tract,
totalLabelCount: detail.totalLabelCount,
labelsCount: Object.entries(detail.labels)
.map(([label, count]) => ({ label, count }))
.sort((a, b) => b.count - a.count)
.map(([name, labelDetail]) => ({
name,
value: labelDetail.count,
articles: labelDetail.articles
}))
.sort((a, b) => b.value - a.value)
.slice(0, 5), // Limit to top 5 labels
}))
.sort((a, b) => b.totalLabelCount - a.totalLabelCount)
.slice(0, 5); // Limit to top 5 tracts

console.log(tractDetailsArray);
return (
<>
<div>
{tractDetailsArray.map((label, index) => (
<Accordion key={label.tract}>
{tractDetailsArray.map((tractDetail, index) => (
<Accordion key={tractDetail.tract}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls={`panel${index + 1}a-content`}
id={`panel${index + 1}a-header`}
>
<Typography color="common.black">{`${label.tract} - ${getNeighborhood(label.tract, neighborhoods)} - ${label.totalLabelCount} articles`}</Typography>
<Typography color="common.black">{`${
tractDetail.tract
} - ${getNeighborhood(tractDetail.tract, neighborhoods)} - ${
tractDetail.totalLabelCount
} articles`}</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography color="common.black">
{label.labelsCount.map((tract) => (
<li key={tract.label}>
{`${tract.label} - ${tract.count} articles`}
</li>
))}
</Typography>

<BubbleChart bubbleData={tractDetail.labelsCount}></BubbleChart>
</AccordionDetails>
</Accordion>
))}
Expand All @@ -185,16 +190,16 @@ const getTractDetailsWithTotalCount = (
};


const wrapper = (flag: boolean,
articles: Article[],
neighborhoods: { [key: string]: string[] }
): React.ReactElement<any, any> => {

return flag ? getLabelDetailsWithLimitedTracts(articles, neighborhoods) :getTractDetailsWithTotalCount(articles, neighborhoods)

}


const wrapper = (
flag: boolean,
articles: Article[],
neighborhoods: { [key: string]: string[] }
): React.ReactElement<any, any> => {
return flag
? getLabelDetailsWithLimitedTracts(articles, neighborhoods)
: getTractDetailsWithTotalCount(articles, neighborhoods);
};

interface AccordionProps {
isLabels: boolean;
Expand All @@ -211,7 +216,6 @@ const BasicAccordion: React.FC<AccordionProps> = ({ isLabels }) => {
}
}, [articleData]);


const component = isLabels
? getLabelDetailsWithLimitedTracts(articles, neighborhoodMasterList!)
: getTractDetailsWithTotalCount(articles, neighborhoodMasterList!);
Expand All @@ -220,10 +224,10 @@ const BasicAccordion: React.FC<AccordionProps> = ({ isLabels }) => {
<>
<Card className="body" sx={{ width: "100%" }}>
<CardContent sx={{ width: "100%" }}>
{articles === null || articles.length === 0 ?(
{articles === null || articles.length === 0 ? (
<Callback></Callback>
) : (
wrapper(isLabels,articles, neighborhoodMasterList!)
wrapper(isLabels, articles, neighborhoodMasterList!)
)}
</CardContent>
</Card>
Expand Down
24 changes: 14 additions & 10 deletions frontend/src/components/ArticleCard/ArticleCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import Lottie from "react-lottie-player";
import { useState } from "react";
import { ArticleContext } from "../../contexts/article_context";



const columns = [
{
field: "title",
Expand All @@ -35,25 +33,31 @@ const columns = [
},
{ field: "author", headerName: "Author", width: 130 },
{ field: "publishingDate", headerName: "Publishing Date", width: 120 },
{ field: "neighborhood", headerName: "Neighborhood", width: 580 },
{ field: "neighborhood", headerName: "Neighborhood", width: 200 },
{ field: "censusTract", headerName: "Census Tract", width: 200 },
{ field: "category", headerName: "Category", width: 90 },
];

interface ArticleCardProps {}
interface ArticleCardProps {
optionalArticles?: Article[];
}

const ArticleCard: React.FC<ArticleCardProps> = () => {
const ArticleCard: React.FC<ArticleCardProps> = ({ optionalArticles }) => {
var articleRow: any = [];

const [articles, setArticles] = useState<Article[]>([]);
const { articleData, queryArticleDataType } =
React.useContext(ArticleContext)!;
const { articleData, queryArticleDataType } = React.useContext(ArticleContext)!;




React.useEffect(() => {
if (articleData) {
if (optionalArticles && optionalArticles.length > 0) {
setArticles(optionalArticles);
} else if (articleData) {
setArticles(articleData);
}
}, [articleData]);
}, [articleData, optionalArticles]);


articles.forEach((article, index) => {
articleRow.push({
Expand Down
Loading

0 comments on commit 6a19989

Please sign in to comment.