Xianbao QIAN commited on
Commit
186881d
1 Parent(s): 255b85f

Server side generation

Browse files
Files changed (1) hide show
  1. src/pages/index.tsx +117 -90
src/pages/index.tsx CHANGED
@@ -1,16 +1,11 @@
 
1
  import React, { useState, useEffect } from 'react';
2
- import ActivityCalendar from "react-activity-calendar";
3
  import { Tooltip } from '@mui/material';
4
 
5
- const PROVIDERS_MAP: Record<string, { color: string; authors: string[] }> = {
6
- "BAAI": { color: "#FF7000", authors: ["BAAI"] }, // Vibrant Orange
7
- "DeepSeek": { color: "#1877F2", authors: ["deepseek-ai"] }, // Meta's Blue
8
- "Shanghai AI Lab": { color: "#10A37F", authors: ["internlm", "OpenGVLab", "openmmlab", "Vchitect"] }, // Fresh Green
9
- "Alibaba": { color: "#FF6F00", authors: ["Qwen", "Alibaba-NLP", "alibaba-pai", "DAMO-NLP-SG", 'ali-vilab', 'modelscope', 'FunAudioLLM'] }, // Bright Orange
10
- "ZhipuAI / GLM": { color: "#4285F4", authors: ["THUDM"] }, // Classic Blue
11
- "Tencent": { color: "#1DA1F2", authors: ["TencentARC", "Tencent-Hunyuan", "h94"] }, // Twitter Blue
12
- "Yi/01": { color: "#FF4500", authors: ["01-ai"] }, // Orange-Red
13
- "Multimodal Art Projection (m-a-p)": { color: "#5E35B1", authors: ["m-a-p"] } // Dark Purple, with gradient from Very Light Purple to Dark Purple
14
  }
15
 
16
  interface ModelData {
@@ -24,96 +19,126 @@ interface Activity {
24
  level: number;
25
  }
26
 
27
- export default function OpenSourceHeatmap() {
28
- const [calendarData, setCalendarData] = useState<Record<string, Activity[]>>({});
29
- const [isLoading, setIsLoading] = useState(true);
30
-
31
 
32
- const generateCalendarData = (modelData: ModelData[]) => {
33
- const data: Record<string, Activity[]> = Object.fromEntries(
34
- Object.keys(PROVIDERS_MAP).map(provider => [provider, []])
35
- );
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
- const today = new Date();
38
- const startDate = new Date(today);
39
- startDate.setMonth(today.getMonth() - 11);
40
- startDate.setDate(1);
41
-
42
- // create a map to store counts for each provider and date
43
- const countMap: Record<string, Record<string, number>> = {};
44
-
45
- modelData.forEach(item => {
46
- const dateString = item.createdAt.split('T')[0];
47
- Object.entries(PROVIDERS_MAP).forEach(([provider, { authors }]) => {
48
- if (authors.some(author => item.id.startsWith(author))) {
49
- countMap[provider] = countMap[provider] || {};
50
- countMap[provider][dateString] = (countMap[provider][dateString] || 0) + 1;
51
- }
52
- });
53
  });
 
 
 
 
 
 
 
 
 
 
54
 
55
- // fill in with 0s for days with no activity
56
- for (let d = new Date(startDate); d <= today; d.setDate(d.getDate() + 1)) {
57
- const dateString = d.toISOString().split('T')[0];
58
-
59
- Object.entries(PROVIDERS_MAP).forEach(([provider]) => {
60
- const count = countMap[provider]?.[dateString] || 0;
61
- data[provider].push({ date: dateString, count, level: 0 });
62
- });
63
- }
64
-
65
- // calculate average counts for each provider
66
- const avgCounts = Object.fromEntries(
67
- Object.entries(data).map(([provider, days]) => [
68
- provider,
69
- days.reduce((sum, day) => sum + day.count, 0) / days.length || 0
70
- ])
71
- );
72
 
73
- // assign levels based on count relative to average
74
- Object.entries(data).forEach(([provider, days]) => {
75
- const avgCount = avgCounts[provider];
76
- days.forEach(day => {
77
- day.level =
78
- day.count === 0 ? 0 :
79
- day.count <= avgCount * 0.5 ? 1 :
80
- day.count <= avgCount ? 2 :
81
- day.count <= avgCount * 1.5 ? 3 : 4;
82
- });
83
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
- return data;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  }
 
87
 
88
- const initData = async () => {
89
- try {
90
- const allAuthors = Object.values(PROVIDERS_MAP).flatMap(({ authors }) => authors);
91
- const uniqueAuthors = Array.from(new Set(allAuthors));
92
-
93
- const allModelData = await Promise.all(
94
- uniqueAuthors.map(async (author) => {
95
- const response = await fetch(`https://huggingface.co/api/models?author=${author}&sort=createdAt&direction=-1`);
96
- const data = await response.json();
97
- return data.map((item: any) => ({
98
- createdAt: item.createdAt,
99
- id: item.id,
100
- }));
101
- })
102
- );
103
-
104
- const flatModelData = allModelData.flat();
105
- const calendarData = generateCalendarData(flatModelData);
106
- setCalendarData(calendarData);
107
- } catch (error) {
108
- console.error("Error fetching data:", error);
109
- } finally {
110
- setIsLoading(false);
111
- }
112
- }
113
 
114
  useEffect(() => {
115
- initData();
116
- }, []);
 
 
117
 
118
  return (
119
  <div className="w-full max-w-screen-lg mx-auto p-4">
@@ -161,4 +186,6 @@ export default function OpenSourceHeatmap() {
161
  )}
162
  </div>
163
  );
164
- }
 
 
 
1
+ // pages/index.tsx
2
  import React, { useState, useEffect } from 'react';
3
+ import ActivityCalendar from 'react-activity-calendar';
4
  import { Tooltip } from '@mui/material';
5
 
6
+ interface ProviderInfo {
7
+ color: string;
8
+ authors: string[];
 
 
 
 
 
 
9
  }
10
 
11
  interface ModelData {
 
19
  level: number;
20
  }
21
 
22
+ interface CalendarData {
23
+ [key: string]: Activity[];
24
+ }
 
25
 
26
+ const PROVIDERS_MAP: Record<string, ProviderInfo> = {
27
+ "BAAI": { color: "#FF7000", authors: ["BAAI"] },
28
+ "DeepSeek": { color: "#1877F2", authors: ["deepseek-ai"] },
29
+ "Shanghai AI Lab": { color: "#10A37F", authors: ["internlm", "OpenGVLab", "openmmlab", "Vchitect"] },
30
+ "Alibaba": { color: "#FF6F00", authors: ["Qwen", "Alibaba-NLP", "alibaba-pai", "DAMO-NLP-SG", 'ali-vilab', 'modelscope', 'FunAudioLLM'] },
31
+ "ZhipuAI / GLM": { color: "#4285F4", authors: ["THUDM"] },
32
+ "Tencent": { color: "#1DA1F2", authors: ["TencentARC", "Tencent-Hunyuan", "h94"] },
33
+ "Yi/01": { color: "#FF4500", authors: ["01-ai"] },
34
+ "Multimodal Art Projection (m-a-p)": { color: "#5E35B1", authors: ["m-a-p"] }
35
+ };
36
+
37
+ // Generates calendar data from model data
38
+ const generateCalendarData = (modelData: ModelData[]): CalendarData => {
39
+ const data: CalendarData = Object.fromEntries(
40
+ Object.keys(PROVIDERS_MAP).map(provider => [provider, []])
41
+ );
42
 
43
+ const today = new Date();
44
+ const startDate = new Date(today);
45
+ startDate.setMonth(today.getMonth() - 11);
46
+ startDate.setDate(1);
47
+
48
+ // Create a map to store counts for each provider and date
49
+ const countMap: Record<string, Record<string, number>> = {};
50
+
51
+ modelData.forEach(item => {
52
+ console.log(item);
53
+ const dateString = item.createdAt.split('T')[0];
54
+ Object.entries(PROVIDERS_MAP).forEach(([provider, { authors }]) => {
55
+ if (authors.some(author => item.id.startsWith(author))) {
56
+ countMap[provider] = countMap[provider] || {};
57
+ countMap[provider][dateString] = (countMap[provider][dateString] || 0) + 1;
58
+ }
59
  });
60
+ });
61
+
62
+ // Fill in with 0s for days with no activity
63
+ for (let d = new Date(startDate); d <= today; d.setDate(d.getDate() + 1)) {
64
+ const dateString = d.toISOString().split('T')[0];
65
+ Object.entries(PROVIDERS_MAP).forEach(([provider]) => {
66
+ const count = countMap[provider]?.[dateString] || 0;
67
+ data[provider].push({ date: dateString, count, level: 0 });
68
+ });
69
+ }
70
 
71
+ // Calculate average counts for each provider
72
+ const avgCounts = Object.fromEntries(
73
+ Object.entries(data).map(([provider, days]) => [
74
+ provider,
75
+ days.reduce((sum, day) => sum + day.count, 0) / days.length || 0
76
+ ])
77
+ );
 
 
 
 
 
 
 
 
 
 
78
 
79
+ // Assign levels based on count relative to average
80
+ Object.entries(data).forEach(([provider, days]) => {
81
+ const avgCount = avgCounts[provider];
82
+ days.forEach(day => {
83
+ day.level =
84
+ day.count === 0 ? 0 :
85
+ day.count <= avgCount * 0.5 ? 1 :
86
+ day.count <= avgCount ? 2 :
87
+ day.count <= avgCount * 1.5 ? 3 : 4;
 
88
  });
89
+ });
90
+
91
+ return data;
92
+ };
93
+
94
+ export async function getStaticProps() {
95
+ try {
96
+ const allAuthors = Object.values(PROVIDERS_MAP).flatMap(({ authors }) => authors);
97
+ const uniqueAuthors = Array.from(new Set(allAuthors));
98
+
99
+ const allModelData = await Promise.all(
100
+ uniqueAuthors.map(async (author) => {
101
+ const response = await fetch(`https://huggingface.co/api/models?author=${author}&sort=createdAt&direction=-1`);
102
+ const data = await response.json();
103
+ return data.map((item: any) => ({
104
+ createdAt: item.createdAt,
105
+ id: item.id,
106
+ }));
107
+ })
108
+ );
109
 
110
+ const flatModelData = allModelData.flat();
111
+ const calendarData = generateCalendarData(flatModelData);
112
+
113
+ return {
114
+ props: {
115
+ calendarData,
116
+ },
117
+ revalidate: 60, // Re-generate the page every hour (3600 seconds)
118
+ };
119
+ } catch (error) {
120
+ console.error("Error fetching data:", error);
121
+ return {
122
+ props: {
123
+ calendarData: {},
124
+ },
125
+ revalidate: 1,
126
+ };
127
  }
128
+ }
129
 
130
+ interface OpenSourceHeatmapProps {
131
+ calendarData: CalendarData;
132
+ }
133
+
134
+ const OpenSourceHeatmap: React.FC<OpenSourceHeatmapProps> = ({ calendarData }) => {
135
+ const [isLoading, setIsLoading] = useState(true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
 
137
  useEffect(() => {
138
+ if (calendarData && Object.keys(calendarData).length > 0) {
139
+ setIsLoading(false);
140
+ }
141
+ }, [calendarData]);
142
 
143
  return (
144
  <div className="w-full max-w-screen-lg mx-auto p-4">
 
186
  )}
187
  </div>
188
  );
189
+ }
190
+
191
+ export default OpenSourceHeatmap;