David Pomerenke commited on
Commit
b4a0c57
·
1 Parent(s): 91e29ba

D3 map with countries (without data display)

Browse files
frontend/public/countries.json ADDED
The diff for this file is too large to render. See raw diff
 
frontend/src/App.js CHANGED
@@ -4,6 +4,7 @@ import 'primereact/resources/themes/lara-light-cyan/theme.css'
4
  import ModelTable from './components/ModelTable'
5
  import LanguageTable from './components/LanguageTable'
6
  import DatasetTable from './components/DatasetTable'
 
7
  import AutoComplete from './components/AutoComplete'
8
 
9
  function App () {
@@ -12,7 +13,7 @@ function App () {
12
  const [error, setError] = useState(null)
13
  const [allSuggestions, setAllSuggestions] = useState([])
14
  const [filters, setFilters] = useState([])
15
-
16
  useEffect(() => {
17
  fetch('/results.json')
18
  .then(response => {
@@ -31,6 +32,22 @@ function App () {
31
  })
32
  }, [])
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  useEffect(() => {
35
  if (data) {
36
  const models = data.model_table.map(item => ({ type: 'Model', value: item.model, detail: item.provider, searchText: item.provider.toLowerCase() + ' ' + item.model.toLowerCase() }))
@@ -87,6 +104,17 @@ function App () {
87
  {error && <p>Error: {error}</p>}
88
  {data && (
89
  <>
 
 
 
 
 
 
 
 
 
 
 
90
  <div
91
  style={{
92
  flex: '60vw 100vw 40vw',
 
4
  import ModelTable from './components/ModelTable'
5
  import LanguageTable from './components/LanguageTable'
6
  import DatasetTable from './components/DatasetTable'
7
+ import WorldMap from './components/WorldMap'
8
  import AutoComplete from './components/AutoComplete'
9
 
10
  function App () {
 
13
  const [error, setError] = useState(null)
14
  const [allSuggestions, setAllSuggestions] = useState([])
15
  const [filters, setFilters] = useState([])
16
+ const [topology, setTopology] = useState(null)
17
  useEffect(() => {
18
  fetch('/results.json')
19
  .then(response => {
 
32
  })
33
  }, [])
34
 
35
+ useEffect(() => {
36
+ fetch('/countries.json')
37
+ .then(response => {
38
+ if (!response.ok) {
39
+ throw new Error('Network response was not ok')
40
+ }
41
+ return response.json()
42
+ })
43
+ .then(jsonData => {
44
+ setTopology(jsonData)
45
+ })
46
+ .catch(err => {
47
+ setError(err.message)
48
+ setLoading(false)
49
+ })
50
+ }, [])
51
  useEffect(() => {
52
  if (data) {
53
  const models = data.model_table.map(item => ({ type: 'Model', value: item.model, detail: item.provider, searchText: item.provider.toLowerCase() + ' ' + item.model.toLowerCase() }))
 
104
  {error && <p>Error: {error}</p>}
105
  {data && (
106
  <>
107
+ <div
108
+ style={{
109
+ flex: '100vw 100vw 100vw',
110
+ maxWidth: 'min(100vw, 900px)',
111
+ marginBottom: '2rem'
112
+ }}
113
+ >
114
+ <div id='figure'>
115
+ <WorldMap data={data} topology={topology} />
116
+ </div>
117
+ </div>
118
  <div
119
  style={{
120
  flex: '60vw 100vw 40vw',
frontend/src/components/WorldMap.js ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useRef, useEffect } from 'react';
2
+ import * as d3 from 'd3';
3
+ import { feature } from 'topojson-client';
4
+
5
+ const WorldMap = ({ data, topology }) => {
6
+ const svgRef = useRef(null);
7
+
8
+ useEffect(() => {
9
+ const createMap = async () => {
10
+ // Clear any existing SVG content
11
+ d3.select(svgRef.current).selectAll("*").remove();
12
+
13
+ // Set dimensions
14
+ const width = 800;
15
+ const height = 450;
16
+
17
+ // Create SVG
18
+ const svg = d3.select(svgRef.current)
19
+ .attr("width", width)
20
+ .attr("height", height)
21
+ .attr("viewBox", [0, 0, width, height])
22
+ .attr("style", "max-width: 100%; height: auto;");
23
+
24
+ // Create a projection
25
+ const projection = d3.geoNaturalEarth1()
26
+ .scale(width / 2 / Math.PI)
27
+ .translate([width / 2, height / 2]);
28
+
29
+ // Create a path generator
30
+ const path = d3.geoPath()
31
+ .projection(projection);
32
+
33
+ // Convert TopoJSON to GeoJSON
34
+ const countries = feature(topology, topology.objects.countries);
35
+
36
+ // Draw the map
37
+ svg.append("g")
38
+ .selectAll("path")
39
+ .data(countries.features)
40
+ .join("path")
41
+ .attr("fill", "#ccc") // Grey background
42
+ .attr("d", path)
43
+ .attr("stroke", "#fff")
44
+ .attr("stroke-width", 0.5);
45
+ };
46
+
47
+ createMap();
48
+ }, [data, topology]);
49
+
50
+ return (
51
+ <div className="world-map-container">
52
+ <h2>World Language Distribution</h2>
53
+ <svg ref={svgRef}></svg>
54
+ </div>
55
+ );
56
+ };
57
+
58
+ export default WorldMap;
frontend/src/index.css CHANGED
@@ -58,6 +58,15 @@ html, body, #root {
58
  color: white;
59
  }
60
 
 
 
 
 
 
 
 
 
 
61
  .p-autocomplete-input {
62
  width: max(100%, 40vw);
63
  margin-top: 2vh;
 
58
  color: white;
59
  }
60
 
61
+ #figure {
62
+ width: 100%;
63
+ min-width: 600px;
64
+ height: 600px;
65
+ border: 1px solid #bdbdbd;
66
+ border-radius: 10px;
67
+ padding: 10px;
68
+ }
69
+
70
  .p-autocomplete-input {
71
  width: max(100%, 40vw);
72
  margin-top: 2vh;