cfahlgren1 HF staff commited on
Commit
22aa376
1 Parent(s): b6b0a70

add spaces, datasets created

Browse files
src/components/Heatmap.tsx ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import ActivityCalendar from "react-activity-calendar";
3
+ import { Tooltip } from "@mui/material";
4
+ import Link from "next/link";
5
+
6
+ type HeatmapProps = {
7
+ data: Array<{ date: string; count: number; level: number }>;
8
+ color: string;
9
+ providerName: string;
10
+ };
11
+
12
+ const Heatmap: React.FC<HeatmapProps> = ({ data, color, providerName }) => {
13
+ return (
14
+ <div className="flex flex-col items-center">
15
+ <div className="w-full overflow-x-auto flex justify-center">
16
+ <ActivityCalendar
17
+ data={data}
18
+ theme={{
19
+ dark: ["#161b22", color],
20
+ light: ["#e0e0e0", color],
21
+ }}
22
+ hideTotalCount
23
+ renderBlock={(block, activity) => (
24
+ <Tooltip
25
+ title={`${activity.count} events on ${activity.date}`}
26
+ arrow
27
+ >
28
+ {block}
29
+ </Tooltip>
30
+ )}
31
+ />
32
+ </div>
33
+ <div>
34
+ <p className="text-sm italic light:text-slate-500">
35
+ Models, Datasets, and Spaces created by{" "}
36
+ <Link
37
+ href={`https://huggingface.co/${providerName}`}
38
+ target="_blank"
39
+ rel="noopener noreferrer"
40
+ className="hover:underline text-blue-500"
41
+ >
42
+ {providerName}.
43
+ </Link>
44
+ </p>
45
+ </div>
46
+ </div>
47
+ );
48
+ };
49
+
50
+ export default Heatmap;
src/pages/[author]/index.tsx CHANGED
@@ -1,11 +1,10 @@
1
  import React, { useState, useEffect } from "react";
2
- import ActivityCalendar from "react-activity-calendar";
3
- import { Tooltip } from "@mui/material";
4
  import { GetServerSidePropsContext } from "next";
5
- import { OpenSourceHeatmapProps } from "../../types/heatmap";
6
  import { generateCalendarData } from "../../utils/calendar";
 
7
 
8
- const DEFAULT_COLOR = "#DB4437";
9
 
10
  const OpenSourceHeatmap: React.FC<OpenSourceHeatmapProps> = ({
11
  calendarData,
@@ -21,39 +20,23 @@ const OpenSourceHeatmap: React.FC<OpenSourceHeatmapProps> = ({
21
 
22
  return (
23
  <div className="w-full max-w-screen-lg mx-auto p-4">
24
-
25
  {isLoading ? (
26
  <p className="text-center">Loading...</p>
27
  ) : (
28
- <div className="space-y-8">
29
  {Object.entries(providers)
30
  .sort(
31
  ([keyA], [keyB]) =>
32
  calendarData[keyB].reduce((sum, day) => sum + day.count, 0) -
33
- calendarData[keyA].reduce((sum, day) => sum + day.count, 0),
34
  )
35
  .map(([providerName, { color }]) => (
36
- <div key={providerName} className="flex flex-col items-center">
37
- <h2 className="text-xl font-bold mb-4">{providerName}</h2>
38
- <div className="w-full overflow-x-auto flex justify-center">
39
- <ActivityCalendar
40
- data={calendarData[providerName]}
41
- theme={{
42
- dark: ["#161b22", color],
43
- light: ["#e0e0e0", color],
44
- }}
45
- hideTotalCount
46
- renderBlock={(block, activity) => (
47
- <Tooltip
48
- title={`${activity.count} models created on ${activity.date}`}
49
- arrow
50
- >
51
- {block}
52
- </Tooltip>
53
- )}
54
- />
55
- </div>
56
- </div>
57
  ))}
58
  </div>
59
  )}
@@ -74,17 +57,23 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
74
  };
75
 
76
  try {
77
- const response = await fetch(
78
- `https://huggingface.co/api/models?author=${author}&sort=createdAt&direction=-1`
 
 
 
 
 
 
 
 
 
 
 
79
  );
80
- const data = await response.json();
81
-
82
- const modelData = data.map((item: any) => ({
83
- createdAt: item.createdAt,
84
- id: item.id,
85
- }));
86
 
87
- const calendarData = generateCalendarData(modelData, providers);
 
88
 
89
  return {
90
  props: {
@@ -105,5 +94,4 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
105
  }
106
  }
107
 
108
-
109
  export default OpenSourceHeatmap;
 
1
  import React, { useState, useEffect } from "react";
 
 
2
  import { GetServerSidePropsContext } from "next";
3
+ import { OpenSourceHeatmapProps } from "../../types/heatmap";
4
  import { generateCalendarData } from "../../utils/calendar";
5
+ import Heatmap from "../../components/Heatmap";
6
 
7
+ const DEFAULT_COLOR = "#FF9D00";
8
 
9
  const OpenSourceHeatmap: React.FC<OpenSourceHeatmapProps> = ({
10
  calendarData,
 
20
 
21
  return (
22
  <div className="w-full max-w-screen-lg mx-auto p-4">
 
23
  {isLoading ? (
24
  <p className="text-center">Loading...</p>
25
  ) : (
26
+ <div>
27
  {Object.entries(providers)
28
  .sort(
29
  ([keyA], [keyB]) =>
30
  calendarData[keyB].reduce((sum, day) => sum + day.count, 0) -
31
+ calendarData[keyA].reduce((sum, day) => sum + day.count, 0)
32
  )
33
  .map(([providerName, { color }]) => (
34
+ <Heatmap
35
+ key={providerName}
36
+ data={calendarData[providerName]}
37
+ color={color}
38
+ providerName={providerName}
39
+ />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  ))}
41
  </div>
42
  )}
 
57
  };
58
 
59
  try {
60
+ const entityTypes = ["models", "datasets", "spaces"];
61
+ const allData = await Promise.all(
62
+ entityTypes.map(async (type) => {
63
+ const response = await fetch(
64
+ `https://huggingface.co/api/${type}?author=${author}&sort=createdAt&direction=-1`,
65
+ );
66
+ const data = await response.json();
67
+ return data.map((item: any) => ({
68
+ createdAt: item.createdAt,
69
+ id: item.id,
70
+ type: type,
71
+ }));
72
+ }),
73
  );
 
 
 
 
 
 
74
 
75
+ const flatData = allData.flat();
76
+ const calendarData = generateCalendarData(flatData, providers);
77
 
78
  return {
79
  props: {
 
94
  }
95
  }
96
 
 
97
  export default OpenSourceHeatmap;
src/pages/index.tsx CHANGED
@@ -1,44 +1,55 @@
1
- import React, { useState, useEffect } from 'react';
2
- import ActivityCalendar from "react-activity-calendar";
3
- import { Tooltip } from '@mui/material';
4
  import { generateCalendarData } from "../utils/calendar";
5
- import { OpenSourceHeatmapProps, ProviderInfo, ModelData } from "../types/heatmap";
 
 
 
 
 
6
 
7
  const PROVIDERS_MAP: Record<string, ProviderInfo> = {
8
  "Mistral AI": { color: "#ff7000", authors: ["mistralai"] },
9
- "Meta": { color: "#1877F2", authors: ["facebook", "meta-llama"] },
10
- "OpenAI": { color: "#10A37F", authors: ["openai"] },
11
- "Anthropic": { color: "#cc785c", authors: ["Anthropic"] },
12
- "Google": { color: "#DB4437", authors: ["google"] },
13
  "Allen Institute for AI": { color: "#5E35B1", authors: ["allenai"] },
14
- "Apple": { color: "#0088cc", authors: ["apple"] },
15
- "Microsoft": { color: "#FEB800", authors: ["microsoft"] },
16
- "NVIDIA": { color: "#76B900", authors: ["nvidia"] },
17
- "DeepSeek": { color: "#0088cc", authors: ["deepseek-ai"] },
18
- "Qwen": { color: "#0088cc", authors: ["Qwen"] },
19
  "Cohere For AI": { color: "#4C6EE6", authors: ["CohereForAI"] },
20
- "IBM": { color: "#4C6EE6", authors: ["ibm-granite"] },
21
  "Stability AI": { color: "#A020F0", authors: ["stabilityai"] },
22
  };
23
 
24
  export async function getStaticProps() {
25
  try {
26
- const allAuthors = Object.values(PROVIDERS_MAP).flatMap(({ authors }) => authors);
 
 
27
  const uniqueAuthors = Array.from(new Set(allAuthors));
28
 
29
- const allModelData = await Promise.all(
30
- uniqueAuthors.map(async (author) => {
31
- const response = await fetch(`https://huggingface.co/api/models?author=${author}&sort=createdAt&direction=-1`);
32
- const data = await response.json();
33
- return data.map((item: any) => ({
34
- createdAt: item.createdAt,
35
- id: item.id,
36
- }));
37
- })
 
 
 
 
 
 
38
  );
39
 
40
- const flatModelData: ModelData[] = allModelData.flat();
41
- const calendarData = generateCalendarData(flatModelData, PROVIDERS_MAP);
42
 
43
  return {
44
  props: {
@@ -59,7 +70,10 @@ export async function getStaticProps() {
59
  }
60
  }
61
 
62
- const OpenSourceHeatmap: React.FC<OpenSourceHeatmapProps> = ({ calendarData, providers }) => {
 
 
 
63
  const [isLoading, setIsLoading] = useState(true);
64
 
65
  useEffect(() => {
@@ -70,10 +84,12 @@ const OpenSourceHeatmap: React.FC<OpenSourceHeatmapProps> = ({ calendarData, pro
70
 
71
  return (
72
  <div className="w-full max-w-screen-lg mx-auto p-4">
73
- <h1 className="text-3xl lg:text-5xl mt-16 font-bold text-center mb-2">Hugging Face Heatmap 🤗</h1>
74
- <p className="text-center text-sm mb-8">
75
- The top AI labs and model releases. <br />
76
- Request more heatmaps by{' '}
 
 
77
  <a
78
  href="https://huggingface.co/spaces/cfahlgren1/model-release-heatmap/discussions/new"
79
  target="_blank"
@@ -87,40 +103,26 @@ const OpenSourceHeatmap: React.FC<OpenSourceHeatmapProps> = ({ calendarData, pro
87
  {isLoading ? (
88
  <p className="text-center">Loading...</p>
89
  ) : (
90
- <div className="space-y-8">
91
  {Object.entries(providers)
92
- .sort(([keyA], [keyB]) =>
93
- calendarData[keyB].reduce((sum, day) => sum + day.count, 0) -
94
- calendarData[keyA].reduce((sum, day) => sum + day.count, 0)
 
95
  )
96
  .map(([providerName, { color }]) => (
97
  <div key={providerName} className="flex flex-col items-center">
98
- <h2 className="text-xl font-bold mb-4">{providerName}</h2>
99
- <div className="w-full overflow-x-auto flex justify-center">
100
- <ActivityCalendar
101
- data={calendarData[providerName]}
102
- theme={{
103
- dark: ['#161b22', color],
104
- light: ['#e0e0e0', color],
105
- }}
106
- hideTotalCount
107
- renderBlock={(block, activity) => (
108
- <Tooltip
109
- title={`${activity.count} models created on ${activity.date}`}
110
- arrow
111
- >
112
- {block}
113
- </Tooltip>
114
- )}
115
- />
116
- </div>
117
  </div>
118
- ))
119
- }
120
  </div>
121
  )}
122
  </div>
123
  );
124
- }
125
 
126
  export default OpenSourceHeatmap;
 
1
+ import React, { useState, useEffect } from "react";
 
 
2
  import { generateCalendarData } from "../utils/calendar";
3
+ import {
4
+ OpenSourceHeatmapProps,
5
+ ProviderInfo,
6
+ ModelData,
7
+ } from "../types/heatmap";
8
+ import Heatmap from "../components/Heatmap";
9
 
10
  const PROVIDERS_MAP: Record<string, ProviderInfo> = {
11
  "Mistral AI": { color: "#ff7000", authors: ["mistralai"] },
12
+ Meta: { color: "#1877F2", authors: ["facebook", "meta-llama"] },
13
+ OpenAI: { color: "#10A37F", authors: ["openai"] },
14
+ Anthropic: { color: "#cc785c", authors: ["Anthropic"] },
15
+ Google: { color: "#DB4437", authors: ["google"] },
16
  "Allen Institute for AI": { color: "#5E35B1", authors: ["allenai"] },
17
+ Apple: { color: "#0088cc", authors: ["apple"] },
18
+ Microsoft: { color: "#FEB800", authors: ["microsoft"] },
19
+ NVIDIA: { color: "#76B900", authors: ["nvidia"] },
20
+ DeepSeek: { color: "#0088cc", authors: ["deepseek-ai"] },
21
+ Qwen: { color: "#0088cc", authors: ["Qwen"] },
22
  "Cohere For AI": { color: "#4C6EE6", authors: ["CohereForAI"] },
23
+ IBM: { color: "#4C6EE6", authors: ["ibm-granite"] },
24
  "Stability AI": { color: "#A020F0", authors: ["stabilityai"] },
25
  };
26
 
27
  export async function getStaticProps() {
28
  try {
29
+ const allAuthors = Object.values(PROVIDERS_MAP).flatMap(
30
+ ({ authors }) => authors,
31
+ );
32
  const uniqueAuthors = Array.from(new Set(allAuthors));
33
 
34
+ const entityTypes = ["models", "datasets", "spaces"];
35
+ const allData = await Promise.all(
36
+ uniqueAuthors.flatMap((author) =>
37
+ entityTypes.map(async (type) => {
38
+ const response = await fetch(
39
+ `https://huggingface.co/api/${type}?author=${author}&sort=createdAt&direction=-1`,
40
+ );
41
+ const data = await response.json();
42
+ return data.map((item: any) => ({
43
+ createdAt: item.createdAt,
44
+ id: item.id,
45
+ type: type,
46
+ }));
47
+ }),
48
+ ),
49
  );
50
 
51
+ const flatData: ModelData[] = allData.flat();
52
+ const calendarData = generateCalendarData(flatData, PROVIDERS_MAP);
53
 
54
  return {
55
  props: {
 
70
  }
71
  }
72
 
73
+ const OpenSourceHeatmap: React.FC<OpenSourceHeatmapProps> = ({
74
+ calendarData,
75
+ providers,
76
+ }) => {
77
  const [isLoading, setIsLoading] = useState(true);
78
 
79
  useEffect(() => {
 
84
 
85
  return (
86
  <div className="w-full max-w-screen-lg mx-auto p-4">
87
+ <h1 className="text-3xl lg:text-5xl mt-16 font-bold text-center mb-2">
88
+ Hugging Face Heatmap 🤗
89
+ </h1>
90
+ <p className="text-center text-sm my-8">
91
+ Models, Datasets, and Spaces from the top AI labs. <br />
92
+ Request more heatmaps by{" "}
93
  <a
94
  href="https://huggingface.co/spaces/cfahlgren1/model-release-heatmap/discussions/new"
95
  target="_blank"
 
103
  {isLoading ? (
104
  <p className="text-center">Loading...</p>
105
  ) : (
106
+ <div className="space-y-16">
107
  {Object.entries(providers)
108
+ .sort(
109
+ ([keyA], [keyB]) =>
110
+ calendarData[keyB].reduce((sum, day) => sum + day.count, 0) -
111
+ calendarData[keyA].reduce((sum, day) => sum + day.count, 0),
112
  )
113
  .map(([providerName, { color }]) => (
114
  <div key={providerName} className="flex flex-col items-center">
115
+ <Heatmap
116
+ data={calendarData[providerName]}
117
+ color={color}
118
+ providerName={providerName}
119
+ />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  </div>
121
+ ))}
 
122
  </div>
123
  )}
124
  </div>
125
  );
126
+ };
127
 
128
  export default OpenSourceHeatmap;
src/styles/globals.css CHANGED
@@ -23,4 +23,4 @@ body {
23
  .text-balance {
24
  text-wrap: balance;
25
  }
26
- }
 
23
  .text-balance {
24
  text-wrap: balance;
25
  }
26
+ }
src/utils/calendar.ts CHANGED
@@ -1,66 +1,71 @@
1
- import { ModelData, ProviderInfo, CalendarData, Activity } from "../types/heatmap";
 
 
 
 
 
2
 
3
  export const generateCalendarData = (
4
- modelData: ModelData[],
5
- providers: Record<string, ProviderInfo>,
6
- ): CalendarData => {
7
- const data: Record<string, Activity[]> = Object.fromEntries(
8
- Object.keys(providers).map((provider) => [provider, []]),
9
- );
10
-
11
- const today = new Date();
12
- const startDate = new Date(today);
13
- startDate.setMonth(today.getMonth() - 11);
14
- startDate.setDate(1);
15
-
16
- // create a map to store counts for each provider and date
17
- const countMap: Record<string, Record<string, number>> = {};
18
-
19
- modelData.forEach((item) => {
20
- const dateString = item.createdAt.split("T")[0];
21
- Object.entries(providers).forEach(([provider, { authors }]) => {
22
- if (authors.some((author) => item.id.startsWith(author))) {
23
- countMap[provider] = countMap[provider] || {};
24
- countMap[provider][dateString] =
25
- (countMap[provider][dateString] || 0) + 1;
26
- }
27
- });
28
  });
29
-
30
- // fill in with 0s for days with no activity
31
- for (let d = new Date(startDate); d <= today; d.setDate(d.getDate() + 1)) {
32
- const dateString = d.toISOString().split("T")[0];
33
-
34
- Object.entries(providers).forEach(([provider]) => {
35
- const count = countMap[provider]?.[dateString] || 0;
36
- data[provider].push({ date: dateString, count, level: 0 });
37
- });
38
- }
39
-
40
- // calculate average counts for each provider
41
- const avgCounts = Object.fromEntries(
42
- Object.entries(data).map(([provider, days]) => [
43
- provider,
44
- days.reduce((sum, day) => sum + day.count, 0) / days.length || 0,
45
- ]),
46
- );
47
-
48
- // assign levels based on count relative to average
49
- Object.entries(data).forEach(([provider, days]) => {
50
- const avgCount = avgCounts[provider];
51
- days.forEach((day) => {
52
- day.level =
53
- day.count === 0
54
- ? 0
55
- : day.count <= avgCount * 0.5
56
- ? 1
57
- : day.count <= avgCount
58
- ? 2
59
- : day.count <= avgCount * 1.5
60
- ? 3
61
- : 4;
62
- });
63
  });
64
-
65
- return data;
66
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ ModelData,
3
+ ProviderInfo,
4
+ CalendarData,
5
+ Activity,
6
+ } from "../types/heatmap";
7
 
8
  export const generateCalendarData = (
9
+ modelData: ModelData[],
10
+ providers: Record<string, ProviderInfo>,
11
+ ): CalendarData => {
12
+ const data: Record<string, Activity[]> = Object.fromEntries(
13
+ Object.keys(providers).map((provider) => [provider, []]),
14
+ );
15
+
16
+ const today = new Date();
17
+ const startDate = new Date(today);
18
+ startDate.setMonth(today.getMonth() - 11);
19
+ startDate.setDate(1);
20
+
21
+ // create a map to store counts for each provider and date
22
+ const countMap: Record<string, Record<string, number>> = {};
23
+
24
+ modelData.forEach((item) => {
25
+ const dateString = item.createdAt.split("T")[0];
26
+ Object.entries(providers).forEach(([provider, { authors }]) => {
27
+ if (authors.some((author) => item.id.startsWith(author))) {
28
+ countMap[provider] = countMap[provider] || {};
29
+ countMap[provider][dateString] =
30
+ (countMap[provider][dateString] || 0) + 1;
31
+ }
 
32
  });
33
+ });
34
+
35
+ // fill in with 0s for days with no activity
36
+ for (let d = new Date(startDate); d <= today; d.setDate(d.getDate() + 1)) {
37
+ const dateString = d.toISOString().split("T")[0];
38
+
39
+ Object.entries(providers).forEach(([provider]) => {
40
+ const count = countMap[provider]?.[dateString] || 0;
41
+ data[provider].push({ date: dateString, count, level: 0 });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  });
43
+ }
44
+
45
+ // calculate average counts for each provider
46
+ const avgCounts = Object.fromEntries(
47
+ Object.entries(data).map(([provider, days]) => [
48
+ provider,
49
+ days.reduce((sum, day) => sum + day.count, 0) / days.length || 0,
50
+ ]),
51
+ );
52
+
53
+ // assign levels based on count relative to average
54
+ Object.entries(data).forEach(([provider, days]) => {
55
+ const avgCount = avgCounts[provider];
56
+ days.forEach((day) => {
57
+ day.level =
58
+ day.count === 0
59
+ ? 0
60
+ : day.count <= avgCount * 0.5
61
+ ? 1
62
+ : day.count <= avgCount
63
+ ? 2
64
+ : day.count <= avgCount * 1.5
65
+ ? 3
66
+ : 4;
67
+ });
68
+ });
69
+
70
+ return data;
71
+ };