Spaces:
Running
Running
functional
Browse files- asset-manifest.json +3 -3
- index.html +1 -1
- src/App.js +84 -22
- static/js/main.6c20428f.js +0 -0
- static/js/main.6c20428f.js.LICENSE.txt +41 -0
- static/js/main.6c20428f.js.map +0 -0
asset-manifest.json
CHANGED
@@ -1,15 +1,15 @@
|
|
1 |
{
|
2 |
"files": {
|
3 |
"main.css": "/static/css/main.1e103507.css",
|
4 |
-
"main.js": "/static/js/main.
|
5 |
"static/js/787.0bfccc2a.chunk.js": "/static/js/787.0bfccc2a.chunk.js",
|
6 |
"index.html": "/index.html",
|
7 |
"main.1e103507.css.map": "/static/css/main.1e103507.css.map",
|
8 |
-
"main.
|
9 |
"787.0bfccc2a.chunk.js.map": "/static/js/787.0bfccc2a.chunk.js.map"
|
10 |
},
|
11 |
"entrypoints": [
|
12 |
"static/css/main.1e103507.css",
|
13 |
-
"static/js/main.
|
14 |
]
|
15 |
}
|
|
|
1 |
{
|
2 |
"files": {
|
3 |
"main.css": "/static/css/main.1e103507.css",
|
4 |
+
"main.js": "/static/js/main.6c20428f.js",
|
5 |
"static/js/787.0bfccc2a.chunk.js": "/static/js/787.0bfccc2a.chunk.js",
|
6 |
"index.html": "/index.html",
|
7 |
"main.1e103507.css.map": "/static/css/main.1e103507.css.map",
|
8 |
+
"main.6c20428f.js.map": "/static/js/main.6c20428f.js.map",
|
9 |
"787.0bfccc2a.chunk.js.map": "/static/js/787.0bfccc2a.chunk.js.map"
|
10 |
},
|
11 |
"entrypoints": [
|
12 |
"static/css/main.1e103507.css",
|
13 |
+
"static/js/main.6c20428f.js"
|
14 |
]
|
15 |
}
|
index.html
CHANGED
@@ -1 +1 @@
|
|
1 |
-
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="View the like history of a project on huggingface"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>Like History</title><script defer="defer" src="/static/js/main.
|
|
|
1 |
+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="View the like history of a project on huggingface"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>Like History</title><script defer="defer" src="/static/js/main.6c20428f.js"></script><link href="/static/css/main.1e103507.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
src/App.js
CHANGED
@@ -3,36 +3,93 @@ import chartXkcd from "chart.xkcd";
|
|
3 |
|
4 |
const projectTypes = ["model", "dataset", "space"];
|
5 |
|
|
|
|
|
|
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
/**
|
8 |
* 1. User click enter key
|
9 |
* 2. Get model/dataset/space name
|
10 |
-
* 3. Get data from API
|
11 |
* 4. Format data(to 20 points at most)
|
12 |
* 5. Draw line chart
|
13 |
*/
|
14 |
function App() {
|
15 |
-
const [projectType, setProjectType] = useState("
|
16 |
-
const [projectName, setProjectName] = useState("");
|
17 |
|
18 |
-
const onSubmit = () => {
|
19 |
const svg = document.querySelector('.line-chart')
|
20 |
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
data: {
|
26 |
-
labels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
|
27 |
datasets: [{
|
28 |
-
label:
|
29 |
-
data:
|
30 |
-
},
|
31 |
-
|
32 |
-
|
33 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
},
|
35 |
-
options: {}
|
36 |
});
|
37 |
}
|
38 |
return (
|
@@ -54,9 +111,9 @@ function App() {
|
|
54 |
className="h-full rounded-md border-0 bg-transparent py-0 pl-3 pr-7 text-gray-500 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm"
|
55 |
onChange={(e) => setProjectType(e.target.value)}
|
56 |
>
|
57 |
-
<option value="
|
58 |
-
<option value="
|
59 |
-
<option value="
|
60 |
</select>
|
61 |
</div>
|
62 |
<input
|
@@ -64,12 +121,17 @@ function App() {
|
|
64 |
name="phone-number"
|
65 |
id="phone-number"
|
66 |
className="block w-full rounded-md border-0 py-1.5 pl-24 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
67 |
-
placeholder="
|
68 |
value={projectName}
|
69 |
onChange={(e) => setProjectName(e.target.value)}
|
70 |
-
|
|
|
71 |
if (e.key === "Enter") {
|
72 |
-
|
|
|
|
|
|
|
|
|
73 |
}
|
74 |
}}
|
75 |
/>
|
|
|
3 |
|
4 |
const projectTypes = ["model", "dataset", "space"];
|
5 |
|
6 |
+
function transformLikesData(likesData) {
|
7 |
+
// Step 1
|
8 |
+
likesData.sort((a, b) => new Date(a.likedAt) - new Date(b.likedAt));
|
9 |
|
10 |
+
// Step 2
|
11 |
+
const cumulativeLikes = {};
|
12 |
+
let cumulativeCount = 0;
|
13 |
+
|
14 |
+
// Step 3
|
15 |
+
likesData.forEach(like => {
|
16 |
+
const date = like.likedAt.split('T')[0];
|
17 |
+
cumulativeCount++;
|
18 |
+
cumulativeLikes[date] = cumulativeCount;
|
19 |
+
});
|
20 |
+
|
21 |
+
// Step 4
|
22 |
+
const transformedData = Object.keys(cumulativeLikes).map(date => ({
|
23 |
+
x: date,
|
24 |
+
y: cumulativeLikes[date].toString()
|
25 |
+
}));
|
26 |
+
|
27 |
+
return transformedData;
|
28 |
+
}
|
29 |
/**
|
30 |
* 1. User click enter key
|
31 |
* 2. Get model/dataset/space name
|
32 |
+
* 3. Get data from API(API format: https://huggingface.co/api/spaces/timqian/like-history/likers?expand[]=likeAt)
|
33 |
* 4. Format data(to 20 points at most)
|
34 |
* 5. Draw line chart
|
35 |
*/
|
36 |
function App() {
|
37 |
+
const [projectType, setProjectType] = useState("models");
|
38 |
+
const [projectName, setProjectName] = useState("openai/whisper-large-v3");
|
39 |
|
40 |
+
const onSubmit = async () => {
|
41 |
const svg = document.querySelector('.line-chart')
|
42 |
|
43 |
+
const res = await fetch(`https://huggingface.co/api/${projectType}/${projectName}/likers?expand[]=likeAt`)
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Format:
|
47 |
+
* [{"user": "timqian", "likedAt": "2021-07-01T00:00:00.000Z"}, {"user": "yy", "likedAt": "2021-07-02T00:00:00.000Z"}]
|
48 |
+
*/
|
49 |
+
const likers = await res.json()
|
50 |
+
|
51 |
+
|
52 |
+
let likeHistory = transformLikesData(likers)
|
53 |
+
|
54 |
+
|
55 |
+
if (likeHistory.length > 40) {
|
56 |
+
// sample 20 points
|
57 |
+
const sampledLikeHistory = []
|
58 |
+
const step = Math.floor(likeHistory.length / 40)
|
59 |
+
for (let i = 0; i < likeHistory.length; i += step) {
|
60 |
+
sampledLikeHistory.push(likeHistory[i])
|
61 |
+
}
|
62 |
+
likeHistory = sampledLikeHistory
|
63 |
+
}
|
64 |
+
|
65 |
+
// if likeHistory is empty, show error message
|
66 |
+
if (likeHistory.length === 0) {
|
67 |
+
alert("No like history found")
|
68 |
+
return
|
69 |
+
}
|
70 |
+
|
71 |
+
new chartXkcd.XY(svg, {
|
72 |
+
title: 'HF like history',
|
73 |
+
xLabel: 'Time',
|
74 |
+
yLabel: 'Likes',
|
75 |
data: {
|
|
|
76 |
datasets: [{
|
77 |
+
label: projectName,
|
78 |
+
data: likeHistory,
|
79 |
+
}],
|
80 |
+
},
|
81 |
+
options: {
|
82 |
+
xTickCount: 3,
|
83 |
+
yTickCount: 4,
|
84 |
+
legendPosition: chartXkcd.config.positionType.upLeft,
|
85 |
+
showLine: true,
|
86 |
+
timeFormat: 'MM/DD/YYYY',
|
87 |
+
dotSize: 0.5,
|
88 |
+
dataColors: ["#dd4528",
|
89 |
+
"#28a3dd",
|
90 |
+
"#f3db52"
|
91 |
+
]
|
92 |
},
|
|
|
93 |
});
|
94 |
}
|
95 |
return (
|
|
|
111 |
className="h-full rounded-md border-0 bg-transparent py-0 pl-3 pr-7 text-gray-500 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm"
|
112 |
onChange={(e) => setProjectType(e.target.value)}
|
113 |
>
|
114 |
+
<option value="models">Model</option>
|
115 |
+
<option value="datasets">Dataset</option>
|
116 |
+
<option value="spaces">Space</option>
|
117 |
</select>
|
118 |
</div>
|
119 |
<input
|
|
|
121 |
name="phone-number"
|
122 |
id="phone-number"
|
123 |
className="block w-full rounded-md border-0 py-1.5 pl-24 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
124 |
+
placeholder="openai/whisper-large-v3"
|
125 |
value={projectName}
|
126 |
onChange={(e) => setProjectName(e.target.value)}
|
127 |
+
onFocus={(e) => e.target.select()}
|
128 |
+
onKeyDown={async (e) => {
|
129 |
if (e.key === "Enter") {
|
130 |
+
try {
|
131 |
+
await onSubmit();
|
132 |
+
} catch (err) {
|
133 |
+
alert(`No like history found for ${projectName}, please check the name and try again`);
|
134 |
+
}
|
135 |
}
|
136 |
}}
|
137 |
/>
|
static/js/main.6c20428f.js
ADDED
The diff for this file is too large to render.
See raw diff
|
|
static/js/main.6c20428f.js.LICENSE.txt
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @license React
|
5 |
+
* react-dom.production.min.js
|
6 |
+
*
|
7 |
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
8 |
+
*
|
9 |
+
* This source code is licensed under the MIT license found in the
|
10 |
+
* LICENSE file in the root directory of this source tree.
|
11 |
+
*/
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @license React
|
15 |
+
* react-jsx-runtime.production.min.js
|
16 |
+
*
|
17 |
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
18 |
+
*
|
19 |
+
* This source code is licensed under the MIT license found in the
|
20 |
+
* LICENSE file in the root directory of this source tree.
|
21 |
+
*/
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @license React
|
25 |
+
* react.production.min.js
|
26 |
+
*
|
27 |
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
28 |
+
*
|
29 |
+
* This source code is licensed under the MIT license found in the
|
30 |
+
* LICENSE file in the root directory of this source tree.
|
31 |
+
*/
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @license React
|
35 |
+
* scheduler.production.min.js
|
36 |
+
*
|
37 |
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
38 |
+
*
|
39 |
+
* This source code is licensed under the MIT license found in the
|
40 |
+
* LICENSE file in the root directory of this source tree.
|
41 |
+
*/
|
static/js/main.6c20428f.js.map
ADDED
The diff for this file is too large to render.
See raw diff
|
|