1
Fork 0
mirror of https://github.com/pds-nest/nest.git synced 2024-10-16 12:07:27 +00:00

Add chart visualization

This commit is contained in:
Steffo 2021-05-20 13:36:07 +02:00
parent eb56dbbfc2
commit 5a27a8e734
Signed by: steffo
GPG key ID: 6965406171929D01
8 changed files with 137 additions and 23 deletions

View file

@ -0,0 +1,60 @@
import React, { useRef } from "react"
import BoxFull from "./BoxFull"
import ChartComponent from "react-chartjs-2"
export default function BoxChart({chartProps, ...props}) {
const boxContentsRef = useRef(null)
const getCssVar = (variable) => {
const computedStyle = window.getComputedStyle(boxContentsRef.current)
console.debug(variable, computedStyle.getPropertyValue(variable))
return computedStyle.getPropertyValue(variable).trim()
}
return (
<BoxFull
childrenProps={{ref: boxContentsRef}}
{...props}
>
{boxContentsRef.current ?
<ChartComponent
width={boxContentsRef.current.offsetWidth}
height={boxContentsRef.current.offsetHeight}
options={{
responsive: true,
scales: {
x: {
beginAtZero: true,
grid: {
borderColor: getCssVar("--bg-light"),
color: getCssVar("--bg-light"),
},
ticks: {
color: getCssVar("--fg-primary"),
}
},
y: {
beginAtZero: true,
grid: {
borderColor: getCssVar("--bg-light"),
color: getCssVar("--bg-light"),
},
ticks: {
color: getCssVar("--fg-primary"),
}
},
},
elements: {
bar: {
backgroundColor: getCssVar("--fg-primary"),
borderColor: "transparent",
color: getCssVar("--fg-primary"),
},
},
}}
{...chartProps}
/>
: null}
</BoxFull>
)
}

View file

@ -0,0 +1,36 @@
import React from "react"
import BoxFull from "../base/BoxFull"
import BoxChart from "../base/BoxChart"
export default function BoxVisualizationChart({ tweets, ...props }) {
// TODO: translate this
const hours = [...Array(24).keys()].map(hour => hour.toString())
const hourlyTweetCount = Array(24).fill(0)
for(const tweet of tweets) {
const insertDate = new Date(tweet["insert_time"])
const insertHour = insertDate.getHours()
console.log(insertHour)
hourlyTweetCount[insertHour] += 1
}
return (
<BoxChart
header={"Hourly graph"}
chartProps={{
type: "bar",
data: {
labels: hours.map(hour => hour.toString()),
datasets: [
{
label: "Tweets",
data: hourlyTweetCount,
}
],
}
}}
{...props}
/>
)
}

View file

@ -1,14 +0,0 @@
import React from "react"
import BoxFull from "../base/BoxFull"
export default function BoxVisualizationGraph({ children, className, ...props }) {
// TODO: translate this
// TODO: implement this
return (
<BoxFull header={"Hourly graph"} {...props}>
{children}
</BoxFull>
)
}

View file

@ -41,8 +41,6 @@ export default function BoxVisualizationStats({ tweets, words, totalTweetCount,
[tweetContentCount, tweetCount],
)
console.debug(words)
const wordCount = useMemo(
() => words.map(word => word.value).reduce((a, b) => a + b),
[words],

View file

@ -6,6 +6,10 @@ import { faChartBar, faCloud, faMap, faStar } from "@fortawesome/free-solid-svg-
export default function PickerVisualization({ currentTab, setTab, ...props }) {
return (
<div {...props}>
<ButtonIconOnly
onClick={() => setTab("stats")} disabled={currentTab ===
"stats"} color={"Grey"} icon={faStar}
/>
<ButtonIconOnly
onClick={() => setTab("wordcloud")} disabled={currentTab ===
"wordcloud"} color={"Grey"} icon={faCloud}
@ -15,10 +19,6 @@ export default function PickerVisualization({ currentTab, setTab, ...props }) {
"histogram"} color={"Grey"} icon={faChartBar}
/>
<ButtonIconOnly onClick={() => setTab("map")} disabled={currentTab === "map"} color={"Grey"} icon={faMap}/>
<ButtonIconOnly
onClick={() => setTab("stats")} disabled={currentTab ===
"stats"} color={"Grey"} icon={faStar}
/>
</div>
)
}

View file

@ -12,7 +12,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { useParams } from "react-router"
import Loading from "../components/base/Loading"
import BoxVisualizationStats from "../components/interactive/BoxVisualizationStats"
import BoxVisualizationGraph from "../components/interactive/BoxVisualizationGraph"
import BoxVisualizationChart from "../components/interactive/BoxVisualizationChart"
import BoxVisualizationMap from "../components/interactive/BoxVisualizationMap"
import BoxVisualizationWordcloud from "../components/interactive/BoxVisualizationWordcloud"
import BoxFull from "../components/base/BoxFull"
@ -25,7 +25,7 @@ export default function PageRepository({ className, ...props }) {
const { id } = useParams()
const { strings } = useContext(ContextLanguage)
const [visualizationTab, setVisualizationTab] = useState("wordcloud")
const [visualizationTab, setVisualizationTab] = useState("stats")
const [addFilterTab, setAddFilterTab] = useState("hashtag")
const repositoryBr = useBackendResource(
@ -99,7 +99,7 @@ export default function PageRepository({ className, ...props }) {
/>
: null}
{visualizationTab === "histogram" ?
<BoxVisualizationGraph
<BoxVisualizationChart
className={Style.Wordcloud}
tweets={tweets}
/>

33
package-lock.json generated
View file

@ -22,6 +22,7 @@
"is-string": "^1.0.5",
"leaflet": "^1.7.1",
"react": "^17.0.2",
"react-chartjs-2": "^3.0.3",
"react-dom": "^17.0.2",
"react-leaflet": ">=3.1.0 <3.2.0 || ^3.2.1",
"react-router": "^5.2.0",
@ -5132,6 +5133,12 @@
"node": ">=10"
}
},
"node_modules/chart.js": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.2.1.tgz",
"integrity": "sha512-XsNDf3854RGZkLCt+5vWAXGAtUdKP2nhfikLGZqud6G4CvRE2ts64TIxTTfspOin2kEZvPgomE29E6oU02dYjQ==",
"peer": true
},
"node_modules/check-types": {
"version": "11.1.2",
"resolved": "https://registry.npmjs.org/check-types/-/check-types-11.1.2.tgz",
@ -16155,6 +16162,18 @@
"react-scripts": ">=2.1.3"
}
},
"node_modules/react-chartjs-2": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-3.0.3.tgz",
"integrity": "sha512-jOFZKwZ8sMLkddewZ/tToxuu4pYimAvvY5I6uK+hCpSFT16Pvo2bdHhUoZ0X87zu9I+dx2I+JCqaLN6XhmrbDg==",
"dependencies": {
"lodash": "^4.17.19"
},
"peerDependencies": {
"chart.js": "^3.1.0",
"react": "^16.8.0 || ^17.0.0"
}
},
"node_modules/react-dev-utils": {
"version": "11.0.4",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz",
@ -26645,6 +26664,12 @@
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
"integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="
},
"chart.js": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.2.1.tgz",
"integrity": "sha512-XsNDf3854RGZkLCt+5vWAXGAtUdKP2nhfikLGZqud6G4CvRE2ts64TIxTTfspOin2kEZvPgomE29E6oU02dYjQ==",
"peer": true
},
"check-types": {
"version": "11.1.2",
"resolved": "https://registry.npmjs.org/check-types/-/check-types-11.1.2.tgz",
@ -35334,6 +35359,14 @@
"semver": "^5.6.0"
}
},
"react-chartjs-2": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-3.0.3.tgz",
"integrity": "sha512-jOFZKwZ8sMLkddewZ/tToxuu4pYimAvvY5I6uK+hCpSFT16Pvo2bdHhUoZ0X87zu9I+dx2I+JCqaLN6XhmrbDg==",
"requires": {
"lodash": "^4.17.19"
}
},
"react-dev-utils": {
"version": "11.0.4",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz",

View file

@ -17,6 +17,7 @@
"is-string": "^1.0.5",
"leaflet": "^1.7.1",
"react": "^17.0.2",
"react-chartjs-2": "^3.0.3",
"react-dom": "^17.0.2",
"react-leaflet": ">=3.1.0 <3.2.0 || ^3.2.1",
"react-router": "^5.2.0",