evol-npm-pulse 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/css/me.css +75 -19
- package/css/pulse.css +377 -30
- package/css/themes/dark/bg0.png +0 -0
- package/css/themes/dark/dark.css +80 -0
- package/css/themes/evol-blue/evol-blue.css +80 -0
- package/css/themes/evol-blue/spirals.png +0 -0
- package/css/themes/light/bg0.png +0 -0
- package/css/themes/light/light.css +69 -0
- package/{chart.html → dashboard.html} +34 -6
- package/index.html +33 -11
- package/js/dashboard.js +799 -0
- package/js/npm-data.js +278 -16
- package/js/pulse.js +125 -53
- package/js/theme.js +79 -0
- package/package.json +1 -1
- package/screenshots/cards-dark.png +0 -0
- package/screenshots/dash-dark.png +0 -0
- package/sitemap.xml +1 -1
- package/js/chart.js +0 -134
- package/npm-pulse-charts.png +0 -0
- package/npm-pulse.png +0 -0
package/README.md
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
One page to see how all your npm packages are doing: downloads over the last week, month, or year, a weekly sparkline for each package, the trend against the previous month, and the GitHub stars that go with it.
|
|
4
4
|
|
|
5
5
|
- [See the packages](https://evoluteur.github.io/npm-pulse/)
|
|
6
|
-
- [See the
|
|
6
|
+
- [See the dashboard](https://evoluteur.github.io/npm-pulse/dashboard.html)
|
|
7
7
|
|
|
8
|
-

|
|
9
9
|
|
|
10
|
-

|
|
11
11
|
|
|
12
12
|
Everything is computed in the browser from three public APIs - no backend, no build step, no library:
|
|
13
13
|
|
|
@@ -15,13 +15,15 @@ Everything is computed in the browser from three public APIs - no backend, no bu
|
|
|
15
15
|
- the [npm download counts API](https://github.com/npm/registry/blob/main/docs/download-counts.md) for a year of daily downloads (fetched in a single bulk call),
|
|
16
16
|
- the [GitHub API](https://docs.github.com/en/rest) for stars and forks.
|
|
17
17
|
|
|
18
|
-
The sparklines are 52 weekly buckets drawn as plain SVG, and the charts page shows total downloads month by month plus the ranking of the most downloaded packages.
|
|
18
|
+
The sparklines are 52 weekly buckets drawn as plain SVG, and the charts page shows total downloads month by month plus the ranking of the most downloaded packages. Each panel can be switched between bars, a pie, and a table (top-right toggle); the pie keeps names and values out of the wedges and lists them instead in a color-key legend below the chart.
|
|
19
19
|
|
|
20
20
|
Downloads are recomputed once a day by npm, so the answers are cached in `localStorage` for 6 hours. Use the "Refresh" link to fetch them again.
|
|
21
21
|
|
|
22
22
|
## Use it for your own packages
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
The quickest way is to click the maintainer name in the title and type a different one, or add a `?user=` parameter to the page URL (e.g. `?user=sindresorhus`) - either way it sets both the npm maintainer and the GitHub user (for stars and forks) without editing any file, and carries over between the packages page and the charts page.
|
|
25
|
+
|
|
26
|
+
To make it stick as the default, change the `user` value (at the top of the [/js/npm-data.js](https://github.com/evoluteur/npm-pulse/blob/main/js/npm-data.js) file) to see your packages instead of mine:
|
|
25
27
|
|
|
26
28
|
```js
|
|
27
29
|
const user = "evoluteur"; // npm maintainer whose packages are shown
|
package/css/me.css
CHANGED
|
@@ -1,74 +1,130 @@
|
|
|
1
1
|
/*
|
|
2
2
|
https://evoluteur.github.io/
|
|
3
3
|
(c) 2026 Olivier Giulieri
|
|
4
|
+
|
|
5
|
+
Layout only - every color comes from the theme loaded in css/themes
|
|
6
|
+
(see js/theme.js and https://evoluteur.github.io/omg-themes/).
|
|
4
7
|
*/
|
|
5
8
|
|
|
6
9
|
html {
|
|
7
10
|
margin: 0;
|
|
8
11
|
padding: 0;
|
|
9
|
-
scroll-behavior: smooth;
|
|
10
|
-
background: #0288d1 url("spirals.png");
|
|
11
12
|
}
|
|
12
13
|
body {
|
|
13
14
|
margin: 0;
|
|
14
15
|
padding: 0;
|
|
15
|
-
font-family: "
|
|
16
|
+
font-family: "Overpass", sans-serif;
|
|
16
17
|
font-size: 20px;
|
|
17
18
|
font-weight: 300;
|
|
18
19
|
line-height: 1.4em;
|
|
19
|
-
color: white;
|
|
20
20
|
overflow-x: hidden;
|
|
21
21
|
}
|
|
22
22
|
h1,
|
|
23
23
|
h2 {
|
|
24
|
-
color:
|
|
24
|
+
color: var(--heading);
|
|
25
25
|
}
|
|
26
26
|
h1 {
|
|
27
27
|
font-size: 2.5rem;
|
|
28
28
|
}
|
|
29
29
|
a,
|
|
30
30
|
a:visited {
|
|
31
|
-
color:
|
|
31
|
+
color: var(--link);
|
|
32
32
|
text-decoration: none;
|
|
33
33
|
font-weight: 400;
|
|
34
|
-
/* background-color: #2b88d2; */
|
|
35
34
|
}
|
|
36
35
|
a:active,
|
|
37
36
|
a:hover {
|
|
38
|
-
color:
|
|
37
|
+
color: var(--link-hover);
|
|
39
38
|
text-decoration: underline;
|
|
40
39
|
font-weight: 400;
|
|
41
40
|
}
|
|
42
41
|
footer {
|
|
43
|
-
color:
|
|
44
|
-
margin: 50px 20px 10px 20px;
|
|
42
|
+
color: var(--muted);
|
|
43
|
+
margin: 50px 20px 10px calc(20px + var(--content-left, 0px));
|
|
45
44
|
> a {
|
|
46
45
|
white-space: nowrap;
|
|
47
46
|
}
|
|
48
47
|
&:hover {
|
|
49
|
-
color:
|
|
48
|
+
color: var(--text);
|
|
50
49
|
}
|
|
51
50
|
}
|
|
52
51
|
|
|
53
52
|
.nav {
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
display: flex;
|
|
54
|
+
flex-wrap: wrap;
|
|
55
|
+
align-items: center;
|
|
56
|
+
justify-content: space-between;
|
|
57
|
+
gap: 20px;
|
|
58
|
+
color: var(--nav-text);
|
|
59
|
+
background-color: var(--nav-bg);
|
|
56
60
|
padding: 8px 10px;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
/* the breadcrumb only: the theme picker keeps its own swatch colors */
|
|
62
|
+
.crumbs a {
|
|
63
|
+
color: var(--nav-link);
|
|
64
|
+
background-color: inherit !important;
|
|
60
65
|
text-decoration: none;
|
|
61
66
|
&:hover {
|
|
62
|
-
color:
|
|
67
|
+
color: var(--nav-link-hover);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* theme picker, same widget as OMG Themes */
|
|
73
|
+
#omg-theme-picker {
|
|
74
|
+
display: inline-flex;
|
|
75
|
+
align-items: center;
|
|
76
|
+
gap: 2px;
|
|
77
|
+
> a {
|
|
78
|
+
display: inline-flex;
|
|
79
|
+
align-items: center;
|
|
80
|
+
justify-content: center;
|
|
81
|
+
height: 28px;
|
|
82
|
+
width: 28px;
|
|
83
|
+
border-radius: 50%;
|
|
84
|
+
border: 1px solid transparent;
|
|
85
|
+
color: var(--nav-link);
|
|
86
|
+
&:hover {
|
|
87
|
+
color: var(--nav-link-hover);
|
|
88
|
+
}
|
|
89
|
+
&.selected {
|
|
90
|
+
color: var(--nav-link-hover);
|
|
63
91
|
}
|
|
64
92
|
}
|
|
65
93
|
}
|
|
94
|
+
|
|
95
|
+
/* the nav bar spans the full width, the content clears the background
|
|
96
|
+
stripe of the light and dark themes */
|
|
66
97
|
.gpc {
|
|
67
98
|
padding: 0 20px;
|
|
99
|
+
padding-left: calc(20px + var(--content-left, 0px));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* wraps the theme picker and the GitHub link on the right of the nav bar */
|
|
103
|
+
.nav-right {
|
|
104
|
+
display: inline-flex;
|
|
105
|
+
align-items: center;
|
|
106
|
+
gap: 34px;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.github-link {
|
|
110
|
+
display: inline-flex;
|
|
111
|
+
align-items: center;
|
|
112
|
+
/* the octicon markup hardcodes fill="currentColor" on the <path>, so
|
|
113
|
+
set fill on the path itself rather than relying on the SVG's fill
|
|
114
|
+
to be inherited or on currentColor -- the currentColor + inherited
|
|
115
|
+
color approach was painting the wrong color (nearly invisible in
|
|
116
|
+
the light theme) until :hover forced a repaint */
|
|
117
|
+
svg path {
|
|
118
|
+
fill: var(--nav-link);
|
|
119
|
+
}
|
|
120
|
+
&:hover svg path {
|
|
121
|
+
fill: var(--nav-link-hover);
|
|
122
|
+
}
|
|
68
123
|
}
|
|
124
|
+
|
|
69
125
|
@media print {
|
|
70
|
-
|
|
71
|
-
|
|
126
|
+
.nav-right {
|
|
127
|
+
display: none;
|
|
72
128
|
}
|
|
73
129
|
@page {
|
|
74
130
|
margin: 1cm 1cm;
|
package/css/pulse.css
CHANGED
|
@@ -2,11 +2,133 @@
|
|
|
2
2
|
npm-pulse
|
|
3
3
|
https://evoluteur.github.io/npm-pulse/
|
|
4
4
|
(c) 2026 Olivier Giulieri
|
|
5
|
+
|
|
6
|
+
Colors come from the theme loaded in css/themes (see js/theme.js).
|
|
5
7
|
*/
|
|
6
8
|
|
|
7
|
-
#title
|
|
9
|
+
#title {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-wrap: wrap;
|
|
12
|
+
align-items: center;
|
|
13
|
+
justify-content: space-between;
|
|
14
|
+
gap: 20px;
|
|
15
|
+
}
|
|
16
|
+
#title-main > a {
|
|
8
17
|
text-transform: none;
|
|
9
18
|
}
|
|
19
|
+
.header-links {
|
|
20
|
+
display: inline-flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
gap: 14px;
|
|
23
|
+
}
|
|
24
|
+
/* Meet-the-Fans, in the title next to the site picker */
|
|
25
|
+
.fans-link {
|
|
26
|
+
margin-left: 6px;
|
|
27
|
+
vertical-align: -3px;
|
|
28
|
+
}
|
|
29
|
+
.icon-link {
|
|
30
|
+
display: inline-flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
svg {
|
|
33
|
+
height: 24px;
|
|
34
|
+
width: 24px;
|
|
35
|
+
}
|
|
36
|
+
svg {
|
|
37
|
+
fill: var(--link);
|
|
38
|
+
}
|
|
39
|
+
&:hover svg {
|
|
40
|
+
fill: var(--link-hover);
|
|
41
|
+
}
|
|
42
|
+
&.current svg {
|
|
43
|
+
fill: var(--icon-current);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
.user-input {
|
|
47
|
+
font-family: inherit;
|
|
48
|
+
font-size: 2.5rem;
|
|
49
|
+
font-weight: inherit;
|
|
50
|
+
line-height: inherit;
|
|
51
|
+
color: var(--heading);
|
|
52
|
+
background: transparent;
|
|
53
|
+
border: none;
|
|
54
|
+
border-bottom: 2px dashed transparent;
|
|
55
|
+
padding: 0;
|
|
56
|
+
}
|
|
57
|
+
.user-input:hover,
|
|
58
|
+
.user-input:focus {
|
|
59
|
+
border-bottom-color: var(--heading);
|
|
60
|
+
outline: none;
|
|
61
|
+
}
|
|
62
|
+
.site-picker {
|
|
63
|
+
/* sized to the selected option where the browser supports it */
|
|
64
|
+
field-sizing: content;
|
|
65
|
+
font-family: inherit;
|
|
66
|
+
font-size: 2.5rem;
|
|
67
|
+
font-weight: inherit;
|
|
68
|
+
line-height: inherit;
|
|
69
|
+
color: var(--heading);
|
|
70
|
+
background: transparent;
|
|
71
|
+
border: none;
|
|
72
|
+
border-bottom: 2px dashed transparent;
|
|
73
|
+
padding: 0;
|
|
74
|
+
cursor: pointer;
|
|
75
|
+
&:hover,
|
|
76
|
+
&:focus {
|
|
77
|
+
border-bottom-color: var(--heading);
|
|
78
|
+
outline: none;
|
|
79
|
+
}
|
|
80
|
+
> option {
|
|
81
|
+
font-size: 1rem;
|
|
82
|
+
color: var(--input-text);
|
|
83
|
+
background-color: var(--input-bg);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
.user-edit {
|
|
87
|
+
display: inline-flex;
|
|
88
|
+
align-items: center;
|
|
89
|
+
gap: 8px;
|
|
90
|
+
}
|
|
91
|
+
.edit-icon {
|
|
92
|
+
display: inline-flex;
|
|
93
|
+
align-items: center;
|
|
94
|
+
background: none;
|
|
95
|
+
border: none;
|
|
96
|
+
padding: 0;
|
|
97
|
+
cursor: pointer;
|
|
98
|
+
color: var(--heading);
|
|
99
|
+
}
|
|
100
|
+
.edit-icon:hover {
|
|
101
|
+
color: var(--text);
|
|
102
|
+
}
|
|
103
|
+
.edit-icon svg {
|
|
104
|
+
fill: currentColor;
|
|
105
|
+
width: 18px;
|
|
106
|
+
height: 18px;
|
|
107
|
+
}
|
|
108
|
+
.duration-picker {
|
|
109
|
+
/* sized to the selected option where the browser supports it */
|
|
110
|
+
field-sizing: content;
|
|
111
|
+
font-family: inherit;
|
|
112
|
+
font-size: inherit;
|
|
113
|
+
font-weight: inherit;
|
|
114
|
+
line-height: inherit;
|
|
115
|
+
color: var(--heading);
|
|
116
|
+
background: transparent;
|
|
117
|
+
border: none;
|
|
118
|
+
border-bottom: 2px dashed transparent;
|
|
119
|
+
padding: 0;
|
|
120
|
+
cursor: pointer;
|
|
121
|
+
&:hover,
|
|
122
|
+
&:focus {
|
|
123
|
+
border-bottom-color: var(--heading);
|
|
124
|
+
outline: none;
|
|
125
|
+
}
|
|
126
|
+
> option {
|
|
127
|
+
font-size: 1rem;
|
|
128
|
+
color: var(--input-text);
|
|
129
|
+
background-color: var(--input-bg);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
10
132
|
.totals {
|
|
11
133
|
font-size: 1.2rem;
|
|
12
134
|
white-space: nowrap;
|
|
@@ -26,17 +148,19 @@
|
|
|
26
148
|
}
|
|
27
149
|
input,
|
|
28
150
|
select {
|
|
151
|
+
font-family: inherit;
|
|
29
152
|
font-size: 16px;
|
|
30
153
|
padding: 5px 10px;
|
|
31
154
|
margin-left: 5px;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
155
|
+
color: var(--input-text);
|
|
156
|
+
background-color: var(--input-bg);
|
|
157
|
+
border: 1px solid var(--input-border);
|
|
158
|
+
border-radius: 4px;
|
|
35
159
|
}
|
|
36
160
|
}
|
|
37
161
|
#summary {
|
|
38
162
|
font-size: 0.9em;
|
|
39
|
-
color:
|
|
163
|
+
color: var(--muted);
|
|
40
164
|
}
|
|
41
165
|
|
|
42
166
|
.projects {
|
|
@@ -49,10 +173,10 @@
|
|
|
49
173
|
flex-direction: column;
|
|
50
174
|
justify-content: space-between;
|
|
51
175
|
flex-grow: 1;
|
|
52
|
-
background-color:
|
|
176
|
+
background-color: var(--card-bg);
|
|
53
177
|
width: 300px;
|
|
54
178
|
max-width: 100%;
|
|
55
|
-
border: 3px solid
|
|
179
|
+
border: 3px solid var(--card-border);
|
|
56
180
|
border-radius: 10px;
|
|
57
181
|
padding: 5px 20px 15px;
|
|
58
182
|
.desc {
|
|
@@ -76,7 +200,7 @@
|
|
|
76
200
|
}
|
|
77
201
|
> .dls {
|
|
78
202
|
font-size: 1.1rem;
|
|
79
|
-
color:
|
|
203
|
+
color: var(--card-strong);
|
|
80
204
|
white-space: nowrap;
|
|
81
205
|
}
|
|
82
206
|
}
|
|
@@ -88,22 +212,28 @@
|
|
|
88
212
|
align-items: baseline;
|
|
89
213
|
margin-top: 12px;
|
|
90
214
|
font-size: 0.85em;
|
|
91
|
-
color:
|
|
215
|
+
color: var(--card-foot);
|
|
92
216
|
}
|
|
93
217
|
.lang {
|
|
218
|
+
display: inline-flex;
|
|
219
|
+
align-items: center;
|
|
94
220
|
margin-right: 10px;
|
|
95
|
-
padding: 3px 10px;
|
|
96
|
-
border-radius: 10px;
|
|
97
|
-
border: solid 1px white;
|
|
98
221
|
white-space: nowrap;
|
|
99
222
|
}
|
|
223
|
+
.lang-dot {
|
|
224
|
+
display: inline-block;
|
|
225
|
+
width: 12px;
|
|
226
|
+
height: 12px;
|
|
227
|
+
margin-right: 6px;
|
|
228
|
+
border-radius: 50%;
|
|
229
|
+
}
|
|
100
230
|
.trend {
|
|
101
231
|
white-space: nowrap;
|
|
102
232
|
&.up {
|
|
103
|
-
color:
|
|
233
|
+
color: var(--up);
|
|
104
234
|
}
|
|
105
235
|
&.down {
|
|
106
|
-
color:
|
|
236
|
+
color: var(--down);
|
|
107
237
|
}
|
|
108
238
|
}
|
|
109
239
|
.crud-icon {
|
|
@@ -126,17 +256,17 @@
|
|
|
126
256
|
height: 46px;
|
|
127
257
|
overflow: visible;
|
|
128
258
|
> polygon {
|
|
129
|
-
fill:
|
|
259
|
+
fill: var(--spark-fill);
|
|
130
260
|
}
|
|
131
261
|
> polyline {
|
|
132
262
|
fill: none;
|
|
133
|
-
stroke:
|
|
263
|
+
stroke: var(--spark-line);
|
|
134
264
|
stroke-width: 1.5;
|
|
135
265
|
stroke-linejoin: round;
|
|
136
266
|
vector-effect: non-scaling-stroke;
|
|
137
267
|
}
|
|
138
268
|
> circle {
|
|
139
|
-
fill:
|
|
269
|
+
fill: var(--spark-line);
|
|
140
270
|
vector-effect: non-scaling-stroke;
|
|
141
271
|
}
|
|
142
272
|
}
|
|
@@ -145,7 +275,7 @@
|
|
|
145
275
|
display: flex;
|
|
146
276
|
align-items: center;
|
|
147
277
|
font-size: 0.85em;
|
|
148
|
-
color:
|
|
278
|
+
color: var(--card-foot);
|
|
149
279
|
}
|
|
150
280
|
|
|
151
281
|
.noresults {
|
|
@@ -153,46 +283,243 @@
|
|
|
153
283
|
padding: 30px;
|
|
154
284
|
}
|
|
155
285
|
|
|
156
|
-
/* charts page */
|
|
286
|
+
/* charts page - the charts sit on a panel, like github-projects-cards */
|
|
287
|
+
.chart-row {
|
|
288
|
+
display: flex;
|
|
289
|
+
flex-wrap: wrap;
|
|
290
|
+
gap: 24px;
|
|
291
|
+
> .series-panel {
|
|
292
|
+
flex: 1 1 300px;
|
|
293
|
+
min-width: 0;
|
|
294
|
+
margin: 0;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
.panels-note {
|
|
298
|
+
font-size: 0.85em;
|
|
299
|
+
color: var(--muted);
|
|
300
|
+
margin: 0 0 12px 0;
|
|
301
|
+
}
|
|
302
|
+
.chart-head {
|
|
303
|
+
display: flex;
|
|
304
|
+
align-items: center;
|
|
305
|
+
justify-content: space-between;
|
|
306
|
+
gap: 12px;
|
|
307
|
+
}
|
|
308
|
+
.chart-toggle {
|
|
309
|
+
display: inline-flex;
|
|
310
|
+
gap: 4px;
|
|
311
|
+
> button {
|
|
312
|
+
display: inline-flex;
|
|
313
|
+
align-items: center;
|
|
314
|
+
padding: 4px;
|
|
315
|
+
cursor: pointer;
|
|
316
|
+
border: 1px solid transparent;
|
|
317
|
+
border-radius: 6px;
|
|
318
|
+
background: none;
|
|
319
|
+
color: var(--panel-muted);
|
|
320
|
+
svg {
|
|
321
|
+
height: 18px;
|
|
322
|
+
width: 18px;
|
|
323
|
+
fill: currentColor;
|
|
324
|
+
}
|
|
325
|
+
&:hover {
|
|
326
|
+
color: var(--panel-text);
|
|
327
|
+
}
|
|
328
|
+
&.selected {
|
|
329
|
+
color: var(--panel-text);
|
|
330
|
+
border-color: var(--panel-grid);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
.data-table {
|
|
335
|
+
width: 100%;
|
|
336
|
+
border-collapse: collapse;
|
|
337
|
+
font-size: 0.85em;
|
|
338
|
+
color: var(--panel-text);
|
|
339
|
+
th,
|
|
340
|
+
td {
|
|
341
|
+
text-align: left;
|
|
342
|
+
padding: 5px 10px;
|
|
343
|
+
border-bottom: 1px solid var(--panel-grid);
|
|
344
|
+
}
|
|
345
|
+
td + td,
|
|
346
|
+
th + th {
|
|
347
|
+
text-align: right;
|
|
348
|
+
width: 22%;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
157
351
|
.chart-block {
|
|
158
|
-
margin: 0 0
|
|
352
|
+
margin: 0 0 24px 0;
|
|
353
|
+
padding: 16px 20px 20px;
|
|
354
|
+
border: 3px solid var(--panel-border);
|
|
355
|
+
border-radius: 10px;
|
|
356
|
+
background: var(--panel-bg);
|
|
357
|
+
color: var(--panel-text);
|
|
159
358
|
> h2 {
|
|
359
|
+
color: var(--heading);
|
|
160
360
|
margin-bottom: 5px;
|
|
161
361
|
}
|
|
162
362
|
> .chart-note {
|
|
163
363
|
font-size: 0.85em;
|
|
164
|
-
color:
|
|
364
|
+
color: var(--panel-muted);
|
|
165
365
|
margin: 0 0 15px 0;
|
|
166
366
|
}
|
|
167
367
|
}
|
|
368
|
+
|
|
369
|
+
/* pies and their legend, also used outside a panel (the shared legend of
|
|
370
|
+
the Stars / Forks / Downloads row) */
|
|
371
|
+
.legend {
|
|
372
|
+
white-space: nowrap;
|
|
373
|
+
text-transform: capitalize;
|
|
374
|
+
}
|
|
375
|
+
/* bars and pie are the same boxes, morphed with CSS transitions
|
|
376
|
+
(ported from react-morph-charts) */
|
|
377
|
+
.morph {
|
|
378
|
+
position: relative;
|
|
379
|
+
width: 100%;
|
|
380
|
+
height: 230px;
|
|
381
|
+
}
|
|
382
|
+
.morph-item {
|
|
383
|
+
position: absolute;
|
|
384
|
+
top: 0;
|
|
385
|
+
left: 0;
|
|
386
|
+
display: flex;
|
|
387
|
+
align-items: center;
|
|
388
|
+
justify-content: center;
|
|
389
|
+
box-sizing: border-box;
|
|
390
|
+
overflow: hidden;
|
|
391
|
+
border-radius: 6px;
|
|
392
|
+
text-align: center;
|
|
393
|
+
contain: layout style paint;
|
|
394
|
+
transition:
|
|
395
|
+
transform 0.7s cubic-bezier(0.22, 1, 0.36, 1),
|
|
396
|
+
width 0.7s cubic-bezier(0.22, 1, 0.36, 1),
|
|
397
|
+
height 0.7s cubic-bezier(0.22, 1, 0.36, 1),
|
|
398
|
+
clip-path 0.7s cubic-bezier(0.22, 1, 0.36, 1);
|
|
399
|
+
}
|
|
400
|
+
.morph.no-transition .morph-item,
|
|
401
|
+
.morph.no-transition .morph-label {
|
|
402
|
+
transition: none;
|
|
403
|
+
}
|
|
404
|
+
.morph-label {
|
|
405
|
+
display: flex;
|
|
406
|
+
flex-direction: column;
|
|
407
|
+
gap: 1px;
|
|
408
|
+
padding: 2px;
|
|
409
|
+
font-size: 0.7rem;
|
|
410
|
+
line-height: 1.15;
|
|
411
|
+
transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
|
|
412
|
+
}
|
|
413
|
+
.morph-name {
|
|
414
|
+
overflow-wrap: anywhere;
|
|
415
|
+
}
|
|
416
|
+
.morph-value {
|
|
417
|
+
font-size: 0.9em;
|
|
418
|
+
opacity: 0.85;
|
|
419
|
+
}
|
|
420
|
+
.morph-item.narrow .morph-name {
|
|
421
|
+
display: none;
|
|
422
|
+
}
|
|
423
|
+
.morph-item.tiny .morph-label {
|
|
424
|
+
display: none;
|
|
425
|
+
}
|
|
426
|
+
.morph-item.pie .morph-label {
|
|
427
|
+
/* names/values already shown in the legend below the pie */
|
|
428
|
+
display: none;
|
|
429
|
+
}
|
|
430
|
+
.pie-legend {
|
|
431
|
+
display: flex;
|
|
432
|
+
flex-wrap: wrap;
|
|
433
|
+
justify-content: center;
|
|
434
|
+
gap: 4px 14px;
|
|
435
|
+
font-size: 0.8em;
|
|
436
|
+
color: var(--muted);
|
|
437
|
+
margin: 4px 0 24px;
|
|
438
|
+
.swatch {
|
|
439
|
+
margin: 0 4px 0 0;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
.pie-key {
|
|
443
|
+
display: inline-flex;
|
|
444
|
+
align-items: center;
|
|
445
|
+
white-space: nowrap;
|
|
446
|
+
}
|
|
447
|
+
.swatch {
|
|
448
|
+
display: inline-block;
|
|
449
|
+
flex: none;
|
|
450
|
+
width: 12px;
|
|
451
|
+
height: 12px;
|
|
452
|
+
border-radius: 3px;
|
|
453
|
+
margin: 0 2px 0 12px;
|
|
454
|
+
&.stars {
|
|
455
|
+
background-color: var(--accent);
|
|
456
|
+
}
|
|
457
|
+
&.forks {
|
|
458
|
+
background-color: var(--fork);
|
|
459
|
+
}
|
|
460
|
+
&.downloads {
|
|
461
|
+
background-color: var(--card-foot);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
168
464
|
.chart {
|
|
169
465
|
width: 100%;
|
|
170
466
|
height: auto;
|
|
171
467
|
overflow: visible;
|
|
172
468
|
.grid {
|
|
173
|
-
stroke:
|
|
469
|
+
stroke: var(--panel-grid);
|
|
174
470
|
stroke-width: 1;
|
|
175
471
|
}
|
|
176
472
|
.bar {
|
|
177
|
-
fill:
|
|
473
|
+
fill: var(--accent);
|
|
178
474
|
}
|
|
179
475
|
.bar.partial {
|
|
180
|
-
fill:
|
|
181
|
-
|
|
476
|
+
fill: var(--accent);
|
|
477
|
+
fill-opacity: 0.45;
|
|
478
|
+
stroke: var(--accent);
|
|
182
479
|
stroke-dasharray: 3 3;
|
|
183
480
|
}
|
|
481
|
+
.bar.stars {
|
|
482
|
+
fill: var(--accent);
|
|
483
|
+
}
|
|
484
|
+
.bar.forks {
|
|
485
|
+
fill: var(--fork);
|
|
486
|
+
}
|
|
487
|
+
.bar.downloads {
|
|
488
|
+
fill: var(--card-foot);
|
|
489
|
+
}
|
|
490
|
+
.bar.up {
|
|
491
|
+
fill: var(--up);
|
|
492
|
+
}
|
|
493
|
+
.bar.down {
|
|
494
|
+
fill: var(--down);
|
|
495
|
+
}
|
|
496
|
+
.zero {
|
|
497
|
+
stroke: var(--panel-grid);
|
|
498
|
+
stroke-width: 1;
|
|
499
|
+
}
|
|
184
500
|
.axis {
|
|
185
|
-
fill:
|
|
501
|
+
fill: var(--panel-text);
|
|
186
502
|
font-size: 12px;
|
|
187
|
-
font-family:
|
|
503
|
+
font-family: inherit;
|
|
188
504
|
}
|
|
189
505
|
.axis.value {
|
|
190
|
-
fill:
|
|
506
|
+
fill: var(--panel-muted);
|
|
191
507
|
}
|
|
192
508
|
.bar-label {
|
|
193
|
-
fill:
|
|
509
|
+
fill: var(--panel-text);
|
|
194
510
|
font-size: 13px;
|
|
195
|
-
font-family:
|
|
511
|
+
font-family: inherit;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/* downloads over the picked period, in its own color */
|
|
516
|
+
.period-chart {
|
|
517
|
+
.bar {
|
|
518
|
+
fill: var(--period-bar);
|
|
519
|
+
}
|
|
520
|
+
.bar.partial {
|
|
521
|
+
fill: var(--period-bar);
|
|
522
|
+
stroke: var(--period-bar);
|
|
196
523
|
}
|
|
197
524
|
}
|
|
198
525
|
|
|
@@ -205,3 +532,23 @@
|
|
|
205
532
|
break-inside: avoid;
|
|
206
533
|
}
|
|
207
534
|
}
|
|
535
|
+
|
|
536
|
+
/* tooltip of the pie slices, following the pointer */
|
|
537
|
+
.chart-tooltip {
|
|
538
|
+
position: fixed;
|
|
539
|
+
z-index: 900;
|
|
540
|
+
display: flex;
|
|
541
|
+
flex-direction: column;
|
|
542
|
+
pointer-events: none;
|
|
543
|
+
padding: 6px 10px;
|
|
544
|
+
border-radius: 6px;
|
|
545
|
+
font-size: 0.8rem;
|
|
546
|
+
line-height: 1.3;
|
|
547
|
+
white-space: nowrap;
|
|
548
|
+
color: var(--nav-text);
|
|
549
|
+
background-color: var(--nav-bg);
|
|
550
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
551
|
+
&[hidden] {
|
|
552
|
+
display: none;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
Binary file
|