From b9e4251b04889865617a4c00b4b3f67da2cee449 Mon Sep 17 00:00:00 2001 From: Shingo OKAWA Date: Mon, 16 Aug 2021 06:16:50 +0900 Subject: [PATCH] this is temporal --- .../trend/{Timeseries => Count}/styles.tsx | 11 +- .../tweet/trend/{Topics => Topic}/index.tsx | 165 ++++++++++-------- .../tweet/trend/{Topics => Topic}/styles.tsx | 2 +- .../src/contexts/tweet/timeline/types.ts | 12 +- .../src/contexts/tweet/trend/actions.ts | 79 ++------- .../src/contexts/tweet/trend/count.d.ts | 40 +++++ react-js-ui/src/contexts/tweet/trend/index.ts | 32 +--- .../src/contexts/tweet/trend/reducers.ts | 107 +++--------- .../src/contexts/tweet/trend/topic.d.ts | 22 +-- react-js-ui/src/contexts/tweet/trend/types.ts | 8 +- react-js-ui/src/pages/tweet/trend/index.tsx | 31 +--- 11 files changed, 198 insertions(+), 311 deletions(-) rename react-js-ui/src/components/tweet/trend/{Timeseries => Count}/styles.tsx (85%) rename react-js-ui/src/components/tweet/trend/{Topics => Topic}/index.tsx (51%) rename react-js-ui/src/components/tweet/trend/{Topics => Topic}/styles.tsx (98%) create mode 100644 react-js-ui/src/contexts/tweet/trend/count.d.ts diff --git a/react-js-ui/src/components/tweet/trend/Timeseries/styles.tsx b/react-js-ui/src/components/tweet/trend/Count/styles.tsx similarity index 85% rename from react-js-ui/src/components/tweet/trend/Timeseries/styles.tsx rename to react-js-ui/src/components/tweet/trend/Count/styles.tsx index 7a5d64b..57e5fc4 100644 --- a/react-js-ui/src/components/tweet/trend/Timeseries/styles.tsx +++ b/react-js-ui/src/components/tweet/trend/Count/styles.tsx @@ -18,13 +18,12 @@ import * as Themes from "../../../../themes"; const styles = (theme: Themes.Custom.Theme) => MaterialStyles.createStyles({ - box: { + card: { + width: "100%", + marginLeft: "auto", + marginRight: "auto", position: "relative", -// height: "50vh", -// width: "90%", -// marginLeft: "auto", -// marginRight: "auto", -// overflow: 'scroll', + background: "rgb(247, 247, 247)", }, }); diff --git a/react-js-ui/src/components/tweet/trend/Topics/index.tsx b/react-js-ui/src/components/tweet/trend/Topic/index.tsx similarity index 51% rename from react-js-ui/src/components/tweet/trend/Topics/index.tsx rename to react-js-ui/src/components/tweet/trend/Topic/index.tsx index 19ad965..a7d6066 100644 --- a/react-js-ui/src/components/tweet/trend/Topics/index.tsx +++ b/react-js-ui/src/components/tweet/trend/Topic/index.tsx @@ -20,26 +20,37 @@ import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles"; import styles from "./styles"; import * as Context from "../../../../contexts/tweet/trend"; +const beginOf = (date: Date): Date => { + const d = new Date(date); + d.setHours(0, 0, 0, 0); + return d; +}; + +const endOf = (date: Date): Date => { + const d = new Date(date); + d.setHours(24, 0, 0, 0); + return d; +}; + +const getDateString = (date: Date) => + date.toLocaleDateString(undefined, { + weekday: "long", + year: "numeric", + month: "long", + day: "numeric", + }); + interface Props extends WithStyles { - from: Date; - to: Date; + date: Date; } export default withStyles(styles)((props: Props) => { const [model, setModel] = React.useState(null); - const dummy = { - labels: [...Array(10).keys()].map((n) => "#Hashtag" + n), - datasets: [{ - label: "count", - data: [...Array(10).keys()].map((_) => 0), - }], - } as Context.Topic.Model; - React.useEffect(() => { const query = { - from: props.from.getTime(), - to: props.to.getTime(), + from: beginOf(props.date).getTime(), + to: endOf(props.date).getTime(), topN: 10, } as Context.Topic.Query; @@ -57,34 +68,36 @@ export default withStyles(styles)((props: Props) => { .then((json) => { setModel({ labels: json.map((e: Context.Topic.Response) => "#" + e.name), - datasets: [{ - label: "count", - data: json.map((e: Context.Topic.Response) => e.count), - backgroundColor: [ - "rgba( 0, 71, 171, 0.7)", - "rgba( 17, 81, 171, 0.7)", - "rgba( 34, 91, 171, 0.7)", - "rgba( 51, 101, 171, 0.7)", - "rgba( 68, 111, 171, 0.7)", - "rgba( 85, 121, 171, 0.7)", - "rgba(103, 131, 171, 0.7)", - "rgba(120, 141, 171, 0.7)", - "rgba(137, 151, 171, 0.7)", - "rgba(154, 161, 171, 0.7)", - ], - borderColor: [ - "rgb( 0, 71, 171)", - "rgb( 17, 81, 171)", - "rgb( 34, 91, 171)", - "rgb( 51, 101, 171)", - "rgb( 68, 111, 171)", - "rgb( 85, 121, 171)", - "rgb(103, 131, 171)", - "rgb(120, 141, 171)", - "rgb(137, 151, 171)", - "rgb(154, 161, 171)", - ], - }], + datasets: [ + { + label: "count", + data: json.map((e: Context.Topic.Response) => e.count), + backgroundColor: [ + "rgba( 0, 71, 171, 0.7)", + "rgba( 17, 81, 171, 0.7)", + "rgba( 34, 91, 171, 0.7)", + "rgba( 51, 101, 171, 0.7)", + "rgba( 68, 111, 171, 0.7)", + "rgba( 85, 121, 171, 0.7)", + "rgba(103, 131, 171, 0.7)", + "rgba(120, 141, 171, 0.7)", + "rgba(137, 151, 171, 0.7)", + "rgba(154, 161, 171, 0.7)", + ], + borderColor: [ + "rgb( 0, 71, 171)", + "rgb( 17, 81, 171)", + "rgb( 34, 91, 171)", + "rgb( 51, 101, 171)", + "rgb( 68, 111, 171)", + "rgb( 85, 121, 171)", + "rgb(103, 131, 171)", + "rgb(120, 141, 171)", + "rgb(137, 151, 171)", + "rgb(154, 161, 171)", + ], + }, + ], }); }) .catch((reason) => { @@ -92,48 +105,51 @@ export default withStyles(styles)((props: Props) => { }); }, []); -const getDateString = (date: string) => - new Date(date).toLocaleDateString(undefined, { - weekday: "long", - year: "numeric", - month: "long", - day: "numeric", - }); + const dummy = { + labels: [...Array(10).keys()].map((n) => "#Hashtag" + n), + datasets: [ + { + label: "count", + data: [...Array(10).keys()].map((_) => 0), + }, + ], + } as Context.Topic.Model; - const NotEnoughData = () => ( + const emptyTopic = () => ( - + - - Not Enough Data - - + Not Enough Data + + + }} + /> ); - const EnoughData = () => ( + const topic = () => ( - - + + - text: "Hashtags [#]", }, }, - }}/> + }} + /> ); - if (model?.datasets[0]?.data?.length !== 10) return NotEnoughData(); - else return EnoughData(); + if (model?.datasets[0]?.data?.length !== 10) return emptyTopic(); + else return topic(); }); diff --git a/react-js-ui/src/components/tweet/trend/Topics/styles.tsx b/react-js-ui/src/components/tweet/trend/Topic/styles.tsx similarity index 98% rename from react-js-ui/src/components/tweet/trend/Topics/styles.tsx rename to react-js-ui/src/components/tweet/trend/Topic/styles.tsx index 7890e25..d7706fe 100644 --- a/react-js-ui/src/components/tweet/trend/Topics/styles.tsx +++ b/react-js-ui/src/components/tweet/trend/Topic/styles.tsx @@ -19,7 +19,7 @@ import * as Themes from "../../../../themes"; const styles = (_: Themes.Custom.Theme) => MaterialStyles.createStyles({ card: { - width: "90%", + width: "100%", marginLeft: "auto", marginRight: "auto", position: "relative", diff --git a/react-js-ui/src/contexts/tweet/timeline/types.ts b/react-js-ui/src/contexts/tweet/timeline/types.ts index a548e25..85259f2 100644 --- a/react-js-ui/src/contexts/tweet/timeline/types.ts +++ b/react-js-ui/src/contexts/tweet/timeline/types.ts @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export const LOAD = "tweet/timeline/LOAD"; -export const DONE = "tweet/timeline/DONE"; -export const NEW_QUERY = "tweet/timeline/NEW_QUERY"; -export const CLR_QUERY = "tweet/timeline/CLR_QUERY"; -export const OPEN = "tweet/timeline/OPEN"; -export const CLOSE = "tweet/timeline/CLOSE"; +export const LOAD = "tweet/timeline/LOAD"; +export const DONE = "tweet/timeline/DONE"; +export const NEW_QUERY = "tweet/timeline/NEW_QUERY"; +export const CLR_QUERY = "tweet/timeline/CLR_QUERY"; +export const OPEN = "tweet/timeline/OPEN"; +export const CLOSE = "tweet/timeline/CLOSE"; export const NEW_LATEST = "tweet/timeline/NEW_LATEST"; export const ADD_LATEST = "tweet/timeline/ADD_LATEST"; export const CLR_LATEST = "tweet/timeline/CLR_LATEST"; diff --git a/react-js-ui/src/contexts/tweet/trend/actions.ts b/react-js-ui/src/contexts/tweet/trend/actions.ts index 59f41ce..8fed1a3 100644 --- a/react-js-ui/src/contexts/tweet/trend/actions.ts +++ b/react-js-ui/src/contexts/tweet/trend/actions.ts @@ -18,42 +18,11 @@ import * as Topic from "./topic.d"; import * as Timeseries from "./timeseries.d"; import * as Types from "./types"; -export const requestTopics = (dispatch: React.Dispatch>) => { - const to = new Date(); - const from = new Date(); - from.setMonth(to.getMonth() - 2); - const query = { - from: from.getTime(), - to: to.getTime(), - topN: 10, - } as Topic.Query; - - const opts = { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(query), - }; - - fetch(`${process.env.API_ENDPOINT}/tweet/topics`, opts) - .then((res) => { - if (!res.ok) throw new Error(`${res.status} ${res.statusText}`); - return res.json(); - }) - .then((json) => { - dispatch(newTopic(json)) - dispatch(done()) - }) - .catch((reason) => { - console.log(reason); - }); - - return load(); -}; - -export const requestTimeseries = (dispatch: React.Dispatch>) => { +export const requestTimeseries = ( + dispatch: React.Dispatch> +) => { const to = new Date("2021-07-26T02:00:00.000+00:00"); const from = new Date("2021-07-26T00:00:00.000+00:00"); -// from.setMonth(to.getMonth() - 2); const query = { from: from.getTime(), to: to.getTime(), @@ -67,17 +36,17 @@ export const requestTimeseries = (dispatch: React.Dispatch { - if (!res.ok) throw new Error(`${res.status} ${res.statusText}`); - return res.json(); - }) - .then((json) => { - dispatch(newTimeseries(json)) - dispatch(done()) - }) - .catch((reason) => { - console.log(reason); - }); + .then((res) => { + if (!res.ok) throw new Error(`${res.status} ${res.statusText}`); + return res.json(); + }) + .then((json) => { + dispatch(newTimeseries(json)); + dispatch(done()); + }) + .catch((reason) => { + console.log(reason); + }); return load(); }; @@ -92,27 +61,7 @@ const done = () => ({ payload: false, }); -export const newTopic = (json: Topic.Response[]) => ({ - type: Types.NEW_TOPIC, - payload: json, -}); - -export const clrTopic = () => ({ - type: Types.CLR_TOPIC, - payload: [], -}); - export const newTimeseries = (json: Timeseries.Response[]) => ({ type: Types.NEW_TIMESERIES, payload: json, }); - -export const addTimeseries = (json: Timeseries.Response[]) => ({ - type: Types.ADD_TIMESERIES, - payload: json, -}); - -export const clrTimeseries = () => ({ - type: Types.CLR_TIMESERIES, - payload: [], -}); diff --git a/react-js-ui/src/contexts/tweet/trend/count.d.ts b/react-js-ui/src/contexts/tweet/trend/count.d.ts new file mode 100644 index 0000000..e6a178c --- /dev/null +++ b/react-js-ui/src/contexts/tweet/trend/count.d.ts @@ -0,0 +1,40 @@ +/* + * 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. + */ +export interface Model { + datasets: Dataset[]; +} + +export interface Dataset { + label: string; + borderColor: string; + data: Data[]; +} + +export interface Data { + x: string; + y: number; +} + +export interface Query { + from: number; + to: number; + interval: string; +} + +export interface Response { + timestamp: string; + count: number; +} diff --git a/react-js-ui/src/contexts/tweet/trend/index.ts b/react-js-ui/src/contexts/tweet/trend/index.ts index c0b9884..25ff8cf 100644 --- a/react-js-ui/src/contexts/tweet/trend/index.ts +++ b/react-js-ui/src/contexts/tweet/trend/index.ts @@ -19,34 +19,6 @@ import * as Actions from "./actions"; import * as Reducers from "./reducers"; import * as Types from "./types"; import * as Topic from "./topic.d"; -import * as Timeseries from "./timeseries.d"; +import * as Count from "./count.d"; -type ContextType = { - state: Reducers.State; - dispatch: React.Dispatch>; -}; - -const store = React.createContext({} as ContextType); - -const init = Reducers.initState; - -const reducer = (state = init, action: Action.WithPayload) => { - switch (action.type) { - case Types.LOAD: - return Reducers.onLoad(state, action); - case Types.DONE: - return Reducers.onDone(state, action); - case Types.NEW_TOPIC: - return Reducers.onNewTopic(state, action); - case Types.CLR_TOPIC: - return Reducers.onClrTopic(state, action); - case Types.NEW_TIMESERIES: - return Reducers.onNewTimeseries(state, action); - case Types.CLR_TIMESERIES: - return Reducers.onClrTimeseries(state, action); - default: - return state; - } -}; - -export { store, reducer, Topic, Timeseries, init, Actions }; +export { Topic, Count }; diff --git a/react-js-ui/src/contexts/tweet/trend/reducers.ts b/react-js-ui/src/contexts/tweet/trend/reducers.ts index 9356037..ab3844f 100644 --- a/react-js-ui/src/contexts/tweet/trend/reducers.ts +++ b/react-js-ui/src/contexts/tweet/trend/reducers.ts @@ -14,100 +14,43 @@ * limitations under the License. */ import * as Action from "../../action.d"; -import * as Topic from "./topic.d"; import * as Timeseries from "./timeseries.d"; export type State = { - loading: boolean; - topicModel: Topic.Model, - timeseriesModel: Timeseries.Model, + timeseriesModel: Timeseries.Model; }; export const initState = { - loading: false, - topicModel: null, timeseriesModel: null, } as State; -export const onLoad = (state: State, _: Action.WithPayload) => { - return { - ...state, - loading: true, - }; -}; - -export const onDone = (state: State, _: Action.WithPayload) => { - return { - ...state, - loading: false, - }; -}; - -export const onNewTopic = (state: State, action: Action.WithPayload) => { - return { - ...state, - topicModel: { - labels: action.payload.map((e) => "#" + e.name), - datasets: [{ - label: "count", - data: action.payload.map((e) => e.count), - backgroundColor: [ - "rgba( 0, 71, 171, 0.7)", - "rgba( 17, 81, 171, 0.7)", - "rgba( 34, 91, 171, 0.7)", - "rgba( 51, 101, 171, 0.7)", - "rgba( 68, 111, 171, 0.7)", - "rgba( 85, 121, 171, 0.7)", - "rgba(103, 131, 171, 0.7)", - "rgba(120, 141, 171, 0.7)", - "rgba(137, 151, 171, 0.7)", - "rgba(154, 161, 171, 0.7)", - ], - borderColor: [ - "rgb( 0, 71, 171)", - "rgb( 17, 81, 171)", - "rgb( 34, 91, 171)", - "rgb( 51, 101, 171)", - "rgb( 68, 111, 171)", - "rgb( 85, 121, 171)", - "rgb(103, 131, 171)", - "rgb(120, 141, 171)", - "rgb(137, 151, 171)", - "rgb(154, 161, 171)", - ], - }], - }, - }; -}; - -export const onClrTopic = (state: State, _: Action.WithPayload) => { - return { - ...state, - topicModel: null, - }; -}; - -export const onNewTimeseries = (state: State, action: Action.WithPayload) => { +function timestamp(str: string) { + const date = new Date(str); + return date.toLocaleTimeString(undefined, { + hour: "2-digit", + minute: "2-digit", + }); +} + +export const onNewTimeseries = ( + state: State, + action: Action.WithPayload +): State => { return { ...state, timeseriesModel: { - datasets: [{ - label: "count", - data: action.payload.map((e) => { - return { - x: e.timestamp, - y: e.count - }; - }), - borderColor: "rgb(255, 99, 132)", - }], + datasets: [ + { + label: "count", + data: action.payload.map((e) => { + return { + x: timestamp(e.timestamp), + y: e.count, + }; + }), + borderColor: "rgb( 0, 71, 171)", + }, + ], }, }; }; - -export const onClrTimeseries = (state: State, _: Action.WithPayload) => { - return { - ...state, - timeseriesModel: null, - }; -}; diff --git a/react-js-ui/src/contexts/tweet/trend/topic.d.ts b/react-js-ui/src/contexts/tweet/trend/topic.d.ts index e012d51..e33117a 100644 --- a/react-js-ui/src/contexts/tweet/trend/topic.d.ts +++ b/react-js-ui/src/contexts/tweet/trend/topic.d.ts @@ -14,24 +14,24 @@ * limitations under the License. */ export interface Model { - labels: string[], - datasets: Dataset[], + labels: string[]; + datasets: Dataset[]; } export interface Dataset { - label: string, - backgroundColor: string[], - borderColor: string[], - data: number[], + label: string; + backgroundColor: string[]; + borderColor: string[]; + data: number[]; } export interface Query { - from: number, - to: number, - topN: number, + from: number; + to: number; + topN: number; } export interface Response { - name: string, - count: number, + name: string; + count: number; } diff --git a/react-js-ui/src/contexts/tweet/trend/types.ts b/react-js-ui/src/contexts/tweet/trend/types.ts index 6ca2bb3..b5fe83c 100644 --- a/react-js-ui/src/contexts/tweet/trend/types.ts +++ b/react-js-ui/src/contexts/tweet/trend/types.ts @@ -13,10 +13,6 @@ * 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_TOPIC = "tweet/trend/NEW_TOPIC"; -export const CLR_TOPIC = "tweet/trend/CLR_TOPIC"; +export const LOAD = "tweet/trend/LOAD"; +export const DONE = "tweet/trend/DONE"; export const NEW_TIMESERIES = "tweet/trend/NEW_TIMESERIES"; -export const ADD_TIMESERIES = "tweet/trend/NEW_TIMESERIES"; -export const CLR_TIMESERIES = "tweet/trend/CLR_TIMESERIES"; diff --git a/react-js-ui/src/pages/tweet/trend/index.tsx b/react-js-ui/src/pages/tweet/trend/index.tsx index dd27fb5..db41501 100644 --- a/react-js-ui/src/pages/tweet/trend/index.tsx +++ b/react-js-ui/src/pages/tweet/trend/index.tsx @@ -14,40 +14,11 @@ * limitations under the License. */ import React from "react"; -import dynamic from "next/dynamic"; import * as Next from "next"; -//import Timeseries from "../../../components/tweet/trend/Timeseries"; import Chart from "../../../components/tweet/trend/Chart"; -import * as Context from "../../../contexts/tweet/trend"; const Index: Next.NextPage = () => { - const Timeseries = React.useMemo( - () => - dynamic(() => import("../../../components/tweet/trend/Timeseries"), { - loading: () =>

Loading a map...

, - ssr: false, - }), - [] - ); - - interface ContextProps { - children: JSX.Element | JSX.Element[]; - } - - const ContextProvider = (props: ContextProps) => { - const [state, dispatch] = React.useReducer(Context.reducer, Context.init); - return ( - - {props.children} - - ); - }; - - return ( - - - - ); + return ; }; export default Index;