Skip to content

Commit be3a541

Browse files
committed
Updated mockup data
1 parent ae75c4a commit be3a541

File tree

2 files changed

+121
-107
lines changed

2 files changed

+121
-107
lines changed

src/components/dashboard/GHGDashboard.tsx

Lines changed: 110 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import React, { useState, useEffect } from 'react';
1+
import React, { useState, useEffect, useMemo } from 'react';
22
import TopicsSidebar from './TopicsSidebar';
33
import IndicatorsList from './IndicatorsList';
44
import DataVisualization from './DataVisualization';
5-
import { generateTimeSeriesData } from '../../data/mockData'; // Keep for now until we have real time series
5+
import { generateTimeSeriesData } from '../../data/mockData'; // Only keeping this until we have real time series data
66
import type { Topic, Indicator } from './types';
77

88
const GHGDashboard: React.FC = () => {
@@ -12,68 +12,134 @@ const GHGDashboard: React.FC = () => {
1212
const [selectedKeywords, setSelectedKeywords] = useState<string[]>([]);
1313
const [viewMode, setViewMode] = useState<'chart' | 'table'>('chart');
1414
const [indicators, setIndicators] = useState<Indicator[]>([]);
15-
const [topics, setTopics] = useState<Topic[]>([]);
16-
15+
1716
// Fetch indicators from the API
1817
useEffect(() => {
1918
const fetchIndicators = async () => {
2019
try {
2120
const response = await fetch('https://api.unepgrid.ch/stats/v1/indicators?language=eq.en');
2221
const data = await response.json();
2322
setIndicators(data);
24-
25-
// Process collections into topics
26-
const collectionsMap = new Map<number, Topic>();
27-
28-
data.forEach((indicator: Indicator) => {
29-
indicator.collections.forEach(collection => {
30-
if (!collectionsMap.has(collection.id)) {
31-
collectionsMap.set(collection.id, {
32-
id: collection.id,
33-
title: collection.title,
34-
count: 1,
35-
subtopics: []
36-
});
37-
} else {
38-
const topic = collectionsMap.get(collection.id);
39-
if (topic) {
40-
topic.count += 1;
41-
}
42-
}
43-
});
44-
});
45-
46-
setTopics(Array.from(collectionsMap.values()));
4723
} catch (error) {
4824
console.error('Error fetching indicators:', error);
4925
}
5026
};
5127

5228
fetchIndicators();
5329
}, []);
54-
30+
31+
// Derive topics from collections in indicators
32+
const topics = useMemo(() => {
33+
const collectionsMap = new Map<number, Topic>();
34+
35+
indicators.forEach(indicator => {
36+
indicator.collections.forEach(collection => {
37+
if (!collectionsMap.has(collection.id)) {
38+
collectionsMap.set(collection.id, {
39+
id: collection.id,
40+
title: collection.title,
41+
count: 1,
42+
subtopics: [] // We could potentially derive these from the data if needed
43+
});
44+
} else {
45+
const topic = collectionsMap.get(collection.id);
46+
if (topic) {
47+
topic.count += 1;
48+
}
49+
}
50+
});
51+
});
52+
53+
return Array.from(collectionsMap.values());
54+
}, [indicators]);
55+
5556
// Filter indicators based on search term, selected topic, and keywords
56-
const filteredIndicators = indicators.filter(indicator => {
57-
const matchesSearch = indicator.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
58-
indicator.description.toLowerCase().includes(searchTerm.toLowerCase()) ||
59-
indicator.keywords.some(keyword => keyword.toLowerCase().includes(searchTerm.toLowerCase()));
57+
const filteredIndicators = useMemo(() => {
58+
return indicators.filter(indicator => {
59+
const matchesSearch = searchTerm === '' ||
60+
indicator.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
61+
indicator.description.toLowerCase().includes(searchTerm.toLowerCase()) ||
62+
indicator.keywords.some(keyword =>
63+
keyword.toLowerCase().includes(searchTerm.toLowerCase())
64+
);
6065

61-
const matchesTopic = !selectedTopic ||
62-
indicator.collections.some(collection => collection.id === selectedTopic.id);
66+
const matchesTopic = !selectedTopic ||
67+
indicator.collections.some(collection =>
68+
collection.id === selectedTopic.id
69+
);
6370

64-
const matchesKeywords = selectedKeywords.length === 0 ||
65-
selectedKeywords.every(keyword =>
66-
indicator.keywords.includes(keyword)
67-
);
71+
const matchesKeywords = selectedKeywords.length === 0 ||
72+
selectedKeywords.every(keyword =>
73+
indicator.keywords.includes(keyword)
74+
);
6875

69-
return matchesSearch && matchesTopic && matchesKeywords;
70-
});
76+
return matchesSearch && matchesTopic && matchesKeywords;
77+
});
78+
}, [indicators, searchTerm, selectedTopic, selectedKeywords]);
79+
80+
// Calculate dynamic facet counts
81+
const dynamicFacets = useMemo(() => {
82+
// Get counts excluding the selected topic filter
83+
const topicResults = indicators.filter(indicator => {
84+
const matchesSearch = searchTerm === '' ||
85+
indicator.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
86+
indicator.description.toLowerCase().includes(searchTerm.toLowerCase());
87+
88+
const matchesKeywords = selectedKeywords.length === 0 ||
89+
selectedKeywords.every(keyword =>
90+
indicator.keywords.includes(keyword)
91+
);
92+
93+
return matchesSearch && matchesKeywords;
94+
});
95+
96+
// Calculate topic counts
97+
const topicCounts = new Map<number, number>();
98+
topicResults.forEach(indicator => {
99+
indicator.collections.forEach(collection => {
100+
topicCounts.set(
101+
collection.id,
102+
(topicCounts.get(collection.id) || 0) + 1
103+
);
104+
});
105+
});
106+
107+
// Get counts excluding the selected keywords filter
108+
const keywordResults = indicators.filter(indicator => {
109+
const matchesSearch = searchTerm === '' ||
110+
indicator.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
111+
indicator.description.toLowerCase().includes(searchTerm.toLowerCase());
112+
113+
const matchesTopic = !selectedTopic ||
114+
indicator.collections.some(collection =>
115+
collection.id === selectedTopic.id
116+
);
117+
118+
return matchesSearch && matchesTopic;
119+
});
120+
121+
// Calculate keyword counts
122+
const keywordCounts = new Map<string, number>();
123+
keywordResults.forEach(indicator => {
124+
indicator.keywords.forEach(keyword => {
125+
keywordCounts.set(
126+
keyword,
127+
(keywordCounts.get(keyword) || 0) + 1
128+
);
129+
});
130+
});
131+
132+
return {
133+
topicCounts,
134+
keywordCounts
135+
};
136+
}, [indicators, searchTerm, selectedTopic, selectedKeywords]);
71137

72138
// Keep using mock time series data for now
73139
const timeSeriesData = generateTimeSeriesData();
74140

75141
return (
76-
<div className="flex h-screen bg-white">
142+
<div className="flex h-screen overflow-hidden bg-white">
77143
<div className="w-[300px] border-r border-gray-200">
78144
<TopicsSidebar
79145
topics={topics}
@@ -84,10 +150,11 @@ const GHGDashboard: React.FC = () => {
84150
indicators={indicators}
85151
selectedKeywords={selectedKeywords}
86152
setSelectedKeywords={setSelectedKeywords}
153+
dynamicCounts={dynamicFacets}
87154
/>
88155
</div>
89156

90-
<div className="w-[400px] border-r border-gray-200 flex flex-col h-screen overflow-hidden">
157+
<div className="w-[400px] border-r border-gray-200 overflow-hidden">
91158
<IndicatorsList
92159
indicators={filteredIndicators}
93160
selectedIndicator={selectedIndicator}
@@ -96,7 +163,7 @@ const GHGDashboard: React.FC = () => {
96163
/>
97164
</div>
98165

99-
<div className="flex-1 p-6">
166+
<div className="flex-1 p-6 overflow-y-auto">
100167
<DataVisualization
101168
data={timeSeriesData}
102169
selectedIndicator={selectedIndicator}

src/data/mockData.ts

Lines changed: 11 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,4 @@
11
// src/data/mockData.ts
2-
import type { Topic, Indicator } from '../components/dashboard/types';
3-
4-
export const topics: Topic[] = [
5-
{
6-
title: 'Climate change',
7-
count: 89,
8-
subtopics: ['Water', 'Energy', 'Pollution', 'Land cover', 'Disaster Risk', 'Extractives']
9-
},
10-
{
11-
title: 'Biodiversity',
12-
count: 45,
13-
subtopics: []
14-
}
15-
];
16-
17-
export const indicators: Indicator[] = [
18-
{
19-
id: 'total',
20-
title: 'KYOTOGHG emissions by sector: Total excluding LULUCF',
21-
period: '1992-2022',
22-
coverage: '193 countries',
23-
type: 'Global'
24-
},
25-
{
26-
id: 'total_2',
27-
title: 'KYOTOGHG emissions by sector: Total excluding LULUCF',
28-
period: '1992-2022',
29-
coverage: '193 countries',
30-
type: 'Global'
31-
},
32-
{
33-
id: 'agriculture',
34-
title: 'KYOTOGHG emissions by sector: Agriculture',
35-
period: '1992-2022',
36-
coverage: '193 countries',
37-
type: 'Global'
38-
},
39-
{
40-
id: 'energy',
41-
title: 'KYOTOGHG emissions by sector: Energy',
42-
period: '1992-2022',
43-
coverage: '193 countries',
44-
type: 'Global'
45-
},
46-
{
47-
id: 'waste',
48-
title: 'KYOTOGHG emissions by sector: Waste',
49-
period: '1992-2022',
50-
coverage: '193 countries',
51-
type: 'Global'
52-
}
53-
];
54-
55-
export const generateTimeSeriesData = () => {
56-
const years = Array.from({length: 31}, (_, i) => 1992 + i);
57-
return years.map(year => ({
58-
year,
59-
'China': Math.floor(Math.random() * 1000000) + 800000,
60-
'United States': Math.floor(Math.random() * 800000) + 600000,
61-
'India': Math.floor(Math.random() * 600000) + 400000,
62-
'Russian Federation': Math.floor(Math.random() * 400000) + 300000,
63-
'Japan': Math.floor(Math.random() * 300000) + 200000,
64-
}));
65-
};
662

673

684
export const latestNews = [
@@ -86,3 +22,14 @@ export const latestNews = [
8622
}
8723
];
8824

25+
export const generateTimeSeriesData = () => {
26+
const years = Array.from({ length: 30 }, (_, i) => 1993 + i);
27+
return years.map(year => ({
28+
year,
29+
'China': Math.floor(Math.random() * 1000000 + 500000),
30+
'United States': Math.floor(Math.random() * 800000 + 400000),
31+
'India': Math.floor(Math.random() * 600000 + 300000),
32+
'Russian Federation': Math.floor(Math.random() * 400000 + 200000),
33+
'Japan': Math.floor(Math.random() * 300000 + 150000)
34+
}));
35+
};

0 commit comments

Comments
 (0)