Skip to content

Commit

Permalink
Fix #1
Browse files Browse the repository at this point in the history
  • Loading branch information
ognis1205 committed Aug 15, 2021
1 parent b9e4251 commit e9495bf
Show file tree
Hide file tree
Showing 12 changed files with 241 additions and 136 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ on [CLAVIN](https://github.com/Novetta/CLAVIN). Because of my poor implementatio

The above gif image demonstrates a list timeline displaying the latest Tweets ordered from newest to oldest with a specified search query.

<img src="./img/trend.gif?raw=true">

The above gif image demonstrates a trend chart displaying the top most trended hashtags and tweet counts per a minute in the last hour.

## Architecture
<img src="./img/mutad.jpeg?raw=true">

Expand Down
Binary file added img/trend.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions react-js-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ All available functionalities will be shown up on the dashboard page.
The following is a checklist of features and their progress:
- [x] Dashboard
- [x] Automation of Dashboard Page Generation
- [ ] Twitter
- [x] Twitter
- [x] Usual Text Search
- [x] Geoparsing Heatmap
- [ ] Trend Chart
- [x] Trend Chart
- [ ] Misc
- [ ] Unittests
- [ ] Strictly Typed Implementation
Expand Down
51 changes: 51 additions & 0 deletions react-js-ui/src/components/tweet/trend/Chart/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2021 Shingo OKAWA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from "react";
import * as Material from "@material-ui/core";
import Count from "../Count";
import Topic from "../Topic";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import styles from "./styles";

interface Props extends WithStyles<typeof styles> {}

const yesterdayOf = (date: Date): Date => {
const d = new Date(date);
d.setHours(date.getHours() - 24);
return d;
};

export default withStyles(styles, { withTheme: true })((props: Props) => {
const date = new Date();

return (
<Material.Box className={props.classes.box}>
<Material.Paper square className={props.classes.paper}>
<Material.Grid container spacing={1}>
<Material.Grid item xs={12}>
<Count date={date} />
</Material.Grid>
<Material.Grid item xs={6}>
<Topic date={date} />
</Material.Grid>
<Material.Grid item xs={6}>
<Topic date={yesterdayOf(date)} />
</Material.Grid>
</Material.Grid>
</Material.Paper>
</Material.Box>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const LOAD = "tweet/trend/LOAD";
export const DONE = "tweet/trend/DONE";
export const NEW_TIMESERIES = "tweet/trend/NEW_TIMESERIES";
import * as MaterialStyles from "@material-ui/core/styles";
import * as Themes from "../../../../themes";

const styles = (theme: Themes.Custom.Theme) =>
MaterialStyles.createStyles({
box: {
position: theme.pagePosition,
},
paper: {
overflow: "auto",
height: theme.pageHeight,
padding: 25,
},
});

export default styles;
156 changes: 156 additions & 0 deletions react-js-ui/src/components/tweet/trend/Count/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*
* Copyright 2021 Shingo OKAWA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from "react";
import * as Material from "@material-ui/core";
import * as ReactChart from "react-chartjs-2";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import styles from "./styles";
import * as Context from "../../../../contexts/tweet/trend";

const oneHourBeforeOf = (date: Date): Date => {
const d = new Date(date);
d.setHours(date.getHours() - 1);
return d;
};

function timestamp(str: string) {
const date = new Date(str);
return date.toLocaleTimeString(undefined, {
hour: "2-digit",
minute: "2-digit",
});
}

const getDateString = (date: Date) =>
date.toLocaleDateString(undefined, {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
});

interface Props extends WithStyles<typeof styles> {
date: Date;
}

export default withStyles(styles)((props: Props) => {
const [model, setModel] = React.useState<Context.Count.Model>(null);

React.useEffect(() => {
const query = {
from: oneHourBeforeOf(props.date).getTime(),
to: props.date.getTime(),
interval: "1m",
} as Context.Count.Query;

const opts = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(query),
};

fetch(`${process.env.API_ENDPOINT}/tweet/counts`, opts)
.then((res) => {
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
return res.json();
})
.then((json) => {
setModel({
datasets: [
{
label: "count",
data: json.map((e: Context.Count.Response) => {
return {
x: timestamp(e.timestamp),
y: e.count,
};
}),
borderColor: "rgb( 0, 71, 171)",
},
],
});
})
.catch((reason) => {
console.log(reason);
});
}, []);

const dummy = {
datasets: [
{
label: "count",
data: [...Array(60).keys()].map((_) => {
return {
x: "",
y: 0,
};
}),
},
],
} as Context.Topic.Model;

const emptyCount = () => (
<Material.Card className={props.classes.card}>
<Material.CardHeader title={getDateString(props.date)} />
<Material.Divider />
<Material.CardContent>
<Material.Typography variant="h6" className={props.classes.typography}>
Not Enough Data
</Material.Typography>
<ReactChart.Line
data={dummy}
options={{
responsive: true,
plugins: {
legend: {
display: false,
},
title: {
display: false,
},
},
}}
/>
</Material.CardContent>
</Material.Card>
);

const count = () => (
<Material.Card className={props.classes.card}>
<Material.CardHeader title={getDateString(props.date)} />
<Material.Divider />
<Material.CardContent>
<ReactChart.Line
data={model}
options={{
responsive: true,
plugins: {
legend: {
display: false,
},
title: {
display: false,
},
},
}}
/>
</Material.CardContent>
</Material.Card>
);

if (model?.datasets[0]?.data?.length < 30) return emptyCount();
else return count();
});
9 changes: 9 additions & 0 deletions react-js-ui/src/components/tweet/trend/Count/styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ const styles = (theme: Themes.Custom.Theme) =>
position: "relative",
background: "rgb(247, 247, 247)",
},
typography: {
zIndex: 800,
margin: "auto",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
position: "absolute",
color: "rgba( 0, 71, 171, 0.7)",
},
});

export default styles;
2 changes: 1 addition & 1 deletion react-js-ui/src/components/tweet/trend/Topic/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,6 @@ export default withStyles(styles)((props: Props) => {
</Material.Card>
);

if (model?.datasets[0]?.data?.length !== 10) return emptyTopic();
if (model?.datasets[0]?.data?.length < 10) return emptyTopic();
else return topic();
});
67 changes: 0 additions & 67 deletions react-js-ui/src/contexts/tweet/trend/actions.ts

This file was deleted.

5 changes: 0 additions & 5 deletions react-js-ui/src/contexts/tweet/trend/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from "react";
import * as Action from "../../action.d";
import * as Actions from "./actions";
import * as Reducers from "./reducers";
import * as Types from "./types";
import * as Topic from "./topic.d";
import * as Count from "./count.d";

Expand Down
Loading

0 comments on commit e9495bf

Please sign in to comment.