add map and icons pkg
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -24,4 +24,5 @@ yarn-error.log*
|
|||||||
|
|
||||||
.firebase
|
.firebase
|
||||||
|
|
||||||
src/components/testData.json
|
src/components/testData.json
|
||||||
|
public/world-110m.json
|
||||||
|
|||||||
49
package-lock.json
generated
49
package-lock.json
generated
@@ -22,9 +22,11 @@
|
|||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-dropdown": "^1.11.0",
|
"react-dropdown": "^1.11.0",
|
||||||
"react-flip-numbers": "^3.0.8",
|
"react-flip-numbers": "^3.0.8",
|
||||||
|
"react-icons": "^4.10.1",
|
||||||
"react-router-dom": "^6.14.2",
|
"react-router-dom": "^6.14.2",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"react-select": "^5.7.4",
|
"react-select": "^5.7.4",
|
||||||
|
"topojson-client": "^3.1.0",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -16101,6 +16103,14 @@
|
|||||||
"react-simple-animate": "^3.0.1"
|
"react-simple-animate": "^3.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-icons": {
|
||||||
|
"version": "4.10.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.10.1.tgz",
|
||||||
|
"integrity": "sha512-/ngzDP/77tlCfqthiiGNZeYFACw85fUjZtLbedmJ5DTlNDIwETxhwBzdOJ21zj4iJdvc0J3y7yOsX3PpxAJzrw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "17.0.2",
|
"version": "17.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||||
@@ -17835,6 +17845,24 @@
|
|||||||
"node": ">=0.6"
|
"node": ">=0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/topojson-client": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==",
|
||||||
|
"dependencies": {
|
||||||
|
"commander": "2"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"topo2geo": "bin/topo2geo",
|
||||||
|
"topomerge": "bin/topomerge",
|
||||||
|
"topoquantize": "bin/topoquantize"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/topojson-client/node_modules/commander": {
|
||||||
|
"version": "2.20.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||||
|
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||||
|
},
|
||||||
"node_modules/tough-cookie": {
|
"node_modules/tough-cookie": {
|
||||||
"version": "4.1.3",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
||||||
@@ -30629,6 +30657,12 @@
|
|||||||
"react-simple-animate": "^3.0.1"
|
"react-simple-animate": "^3.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-icons": {
|
||||||
|
"version": "4.10.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.10.1.tgz",
|
||||||
|
"integrity": "sha512-/ngzDP/77tlCfqthiiGNZeYFACw85fUjZtLbedmJ5DTlNDIwETxhwBzdOJ21zj4iJdvc0J3y7yOsX3PpxAJzrw==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"react-is": {
|
"react-is": {
|
||||||
"version": "17.0.2",
|
"version": "17.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||||
@@ -31905,6 +31939,21 @@
|
|||||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
|
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
|
||||||
},
|
},
|
||||||
|
"topojson-client": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==",
|
||||||
|
"requires": {
|
||||||
|
"commander": "2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"commander": {
|
||||||
|
"version": "2.20.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||||
|
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"tough-cookie": {
|
"tough-cookie": {
|
||||||
"version": "4.1.3",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "hpos-dashboard",
|
"name": "hpos-web",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -17,9 +17,11 @@
|
|||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-dropdown": "^1.11.0",
|
"react-dropdown": "^1.11.0",
|
||||||
"react-flip-numbers": "^3.0.8",
|
"react-flip-numbers": "^3.0.8",
|
||||||
|
"react-icons": "^4.10.1",
|
||||||
"react-router-dom": "^6.14.2",
|
"react-router-dom": "^6.14.2",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"react-select": "^5.7.4",
|
"react-select": "^5.7.4",
|
||||||
|
"topojson-client": "^3.1.0",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class RegistraionChart extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <div id={"#" + this.props.id} style={{ margin: '1em' }}></div>
|
return <div id="registration" style={{ margin: '1em' }}></div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default RegistraionChart;
|
export default RegistraionChart;
|
||||||
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
|||||||
import * as d3 from 'd3';
|
import * as d3 from 'd3';
|
||||||
import { sgg } from 'ml-savitzky-golay-generalized';
|
import { sgg } from 'ml-savitzky-golay-generalized';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { FaBeer, FaInfo } from "react-icons/fa";
|
||||||
|
|
||||||
import './DeviceGraph.css';
|
import './DeviceGraph.css';
|
||||||
|
|
||||||
@@ -94,6 +95,7 @@ class AbsorbanceGraph extends Component {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className='graph-card'>
|
<div className='graph-card'>
|
||||||
|
{/* <FaInfo /> */}
|
||||||
<div id="wavelength-graph" style={{ margin: '1em' }}>
|
<div id="wavelength-graph" style={{ margin: '1em' }}>
|
||||||
</div>
|
</div>
|
||||||
<div className='graph-title'>wavelength vs absorbance</div>
|
<div className='graph-title'>wavelength vs absorbance</div>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class TestAnalyticsPie extends Component {
|
|||||||
|
|
||||||
drawChart(data) {
|
drawChart(data) {
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
|
||||||
var margin = { top: 60, right: 20, bottom: 30, left: 50 },
|
var margin = { top: 60, right: 20, bottom: 30, left: 50 },
|
||||||
width = 960 - margin.left - margin.right,
|
width = 960 - margin.left - margin.right,
|
||||||
height = 500 - margin.top - margin.bottom,
|
height = 500 - margin.top - margin.bottom,
|
||||||
@@ -56,12 +56,23 @@ class TestAnalyticsPie extends Component {
|
|||||||
.enter().append("g")
|
.enter().append("g")
|
||||||
.attr("class", "arc");
|
.attr("class", "arc");
|
||||||
|
|
||||||
|
var tooltip = d3.select("#category-diagram")
|
||||||
|
.append("div")
|
||||||
|
.style("position", "absolute")
|
||||||
|
.style("z-index", "10")
|
||||||
|
.style("visibility", "hidden")
|
||||||
|
.style("background", "#fff")
|
||||||
|
.text("a simple tooltip");
|
||||||
|
|
||||||
arc.append("path")
|
arc.append("path")
|
||||||
.attr("d", path)
|
.attr("d", path)
|
||||||
.attr("fill", function (d) { return color(d.data.category); });
|
.attr("fill", function (d) { return color(d.data.category); })
|
||||||
|
.on('mouseover', (event, d) => { tooltip.text(`${d.data.category} (${d.data.count})`); console.log(d.data.count); return tooltip.style("visibility", "visible"); });
|
||||||
|
|
||||||
console.log(arc)
|
console.log(arc)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
arc.append("text")
|
arc.append("text")
|
||||||
.attr("transform", function (d) {
|
.attr("transform", function (d) {
|
||||||
return "translate(" + label.centroid(d) + ")";
|
return "translate(" + label.centroid(d) + ")";
|
||||||
|
|||||||
103
src/components/WorldMap.js
Normal file
103
src/components/WorldMap.js
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
import React, { useState, useEffect } from "react"
|
||||||
|
import { geoEqualEarth, geoPath } from "d3-geo"
|
||||||
|
import { feature } from "topojson-client"
|
||||||
|
|
||||||
|
const cities = [
|
||||||
|
{ name: "Tokyo", coordinates: [139.6917,35.6895], population: 37843000 },
|
||||||
|
{ name: "Jakarta", coordinates: [106.8650,-6.1751], population: 30539000 },
|
||||||
|
{ name: "Delhi", coordinates: [77.1025,28.7041], population: 24998000 },
|
||||||
|
{ name: "Manila", coordinates: [120.9842,14.5995], population: 24123000 },
|
||||||
|
{ name: "Seoul", coordinates: [126.9780,37.5665], population: 23480000 },
|
||||||
|
{ name: "Shanghai", coordinates: [121.4737,31.2304], population: 23416000 },
|
||||||
|
{ name: "Karachi", coordinates: [67.0099,24.8615], population: 22123000 },
|
||||||
|
{ name: "Beijing", coordinates: [116.4074,39.9042], population: 21009000 },
|
||||||
|
{ name: "New York", coordinates: [-74.0059,40.7128], population: 20630000 },
|
||||||
|
{ name: "Guangzhou", coordinates: [113.2644,23.1291], population: 20597000 },
|
||||||
|
{ name: "Sao Paulo", coordinates: [-46.6333,-23.5505], population: 20365000 },
|
||||||
|
{ name: "Mexico City", coordinates: [-99.1332,19.4326], population: 20063000 },
|
||||||
|
{ name: "Mumbai", coordinates: [72.8777,19.0760], population: 17712000 },
|
||||||
|
{ name: "Osaka", coordinates: [135.5022,34.6937], population: 17444000 },
|
||||||
|
{ name: "Moscow", coordinates: [37.6173,55.7558], population: 16170000 },
|
||||||
|
{ name: "Dhaka", coordinates: [90.4125,23.8103], population: 15669000 },
|
||||||
|
{ name: "Greater Cairo", coordinates: [31.2357,30.0444], population: 15600000 },
|
||||||
|
{ name: "Los Angeles", coordinates: [-118.2437,34.0522], population: 15058000 },
|
||||||
|
{ name: "Bangkok", coordinates: [100.5018,13.7563], population: 14998000 },
|
||||||
|
{ name: "Kolkata", coordinates: [88.3639,22.5726], population: 14667000 },
|
||||||
|
{ name: "Buenos Aires", coordinates: [-58.3816,-34.6037], population: 14122000 },
|
||||||
|
{ name: "Tehran", coordinates: [51.3890,35.6892], population: 13532000 },
|
||||||
|
{ name: "Istanbul", coordinates: [28.9784,41.0082], population: 13287000 },
|
||||||
|
{ name: "Lagos", coordinates: [3.3792,6.5244], population: 13123000 },
|
||||||
|
{ name: "Shenzhen", coordinates: [114.0579,22.5431], population: 12084000 },
|
||||||
|
{ name: "Rio de Janeiro", coordinates: [-43.1729,-22.9068], population: 11727000 },
|
||||||
|
{ name: "Kinshasa", coordinates: [15.2663,-4.4419], population: 11587000 },
|
||||||
|
{ name: "Tianjin", coordinates: [117.3616,39.3434], population: 10920000 },
|
||||||
|
{ name: "Paris", coordinates: [2.3522,48.8566], population: 10858000 },
|
||||||
|
{ name: "Lima", coordinates: [-77.0428,-12.0464], population: 10750000 },
|
||||||
|
]
|
||||||
|
|
||||||
|
const projection = geoEqualEarth()
|
||||||
|
.scale(160)
|
||||||
|
.translate([ 800 / 2, 450 / 2 ])
|
||||||
|
|
||||||
|
const WorldMap = () => {
|
||||||
|
const [geographies, setGeographies] = useState([])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch("/world-110m.json")
|
||||||
|
.then(response => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
console.log(`There was a problem: ${response.status}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.json().then(worlddata => {
|
||||||
|
setGeographies(feature(worlddata, worlddata.objects.countries).features)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleCountryClick = countryIndex => {
|
||||||
|
console.log("Clicked on country: ", geographies[countryIndex])
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleMarkerClick = i => {
|
||||||
|
console.log("Marker: ", cities[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<svg width={ 800 } height={ 450 } viewBox="0 0 800 450">
|
||||||
|
<g className="countries">
|
||||||
|
{
|
||||||
|
geographies.map((d,i) => (
|
||||||
|
<path
|
||||||
|
key={ `path-${ i }` }
|
||||||
|
d={ geoPath().projection(projection)(d) }
|
||||||
|
className="country"
|
||||||
|
fill={ `rgba(38,50,56,${ 1 / geographies.length * i})` }
|
||||||
|
stroke="#FFFFFF"
|
||||||
|
strokeWidth={ 0.5 }
|
||||||
|
onClick={ () => handleCountryClick(i) }
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</g>
|
||||||
|
<g className="markers">
|
||||||
|
{
|
||||||
|
cities.map((city, i) => (
|
||||||
|
<circle
|
||||||
|
key={ `marker-${i}` }
|
||||||
|
cx={ projection(city.coordinates)[0] }
|
||||||
|
cy={ projection(city.coordinates)[1] }
|
||||||
|
r={ city.population / 3000000 }
|
||||||
|
fill="#E91E63"
|
||||||
|
stroke="#FFFFFF"
|
||||||
|
className="marker"
|
||||||
|
onClick={ () => handleMarkerClick(i) }
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WorldMap
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { getFirestore, collection, getDocs, doc, onSnapshot, query } from "firebase/firestore";
|
import { getFirestore} from "firebase/firestore";
|
||||||
|
|
||||||
import { initializeApp } from "firebase/app";
|
import { initializeApp } from "firebase/app";
|
||||||
import { getAnalytics } from "firebase/analytics";
|
import { getAnalytics } from "firebase/analytics";
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import App from './App';
|
|||||||
import reportWebVitals from './reportWebVitals';
|
import reportWebVitals from './reportWebVitals';
|
||||||
import Devices from './components/Devices';
|
import Devices from './components/Devices';
|
||||||
import TestAnalytics from './components/TestAnalytics';
|
import TestAnalytics from './components/TestAnalytics';
|
||||||
|
import WorldMap from './components/WorldMap';
|
||||||
|
import RegistraionChart from './RegistraionChart';
|
||||||
|
|
||||||
const router = createBrowserRouter([
|
const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
@@ -26,6 +28,10 @@ const router = createBrowserRouter([
|
|||||||
{
|
{
|
||||||
path: "/analytics",
|
path: "/analytics",
|
||||||
element: <TestAnalytics />,
|
element: <TestAnalytics />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/map",
|
||||||
|
element: <RegistraionChart />,
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user