Skip to content

Commit 9e7f4b9

Browse files
committed
Downloads chart: show several version modes
1 parent f99f380 commit 9e7f4b9

File tree

4 files changed

+90
-4
lines changed

4 files changed

+90
-4
lines changed

app/lib/frontend/dom/material.dart

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,3 +436,31 @@ d.Node option({
436436
],
437437
);
438438
}
439+
440+
d.Node radioButtons({
441+
required String name,
442+
required List<({String id, String value})> idsAndValues,
443+
String? checkedId,
444+
Iterable<String>? classes,
445+
String? leadingText,
446+
}) {
447+
final nodes = <d.Node>[];
448+
if (leadingText != null) {
449+
nodes.add(d.strong(text: leadingText));
450+
}
451+
idsAndValues.forEach((e) {
452+
nodes.add(d.input(
453+
id: e.id,
454+
type: 'radio',
455+
name: name,
456+
value: e.value,
457+
classes: [
458+
...?classes,
459+
],
460+
attributes: {if (e.id == checkedId) 'checked': ''},
461+
));
462+
nodes.add(d.label(attributes: {'for': e.id}, child: d.text(e.value)));
463+
});
464+
465+
return d.div(classes: ['mdc-form-field'], children: nodes);
466+
}

app/lib/frontend/templates/views/pkg/score_tab.dart

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'dart:convert';
77
import 'package:_pub_shared/data/download_counts_data.dart';
88
import 'package:_pub_shared/format/number_format.dart';
99
import 'package:pana/models.dart';
10+
import 'package:pub_dev/frontend/dom/material.dart';
1011
import 'package:pub_dev/service/download_counts/backend.dart';
1112
import 'package:pub_dev/shared/utils.dart';
1213

@@ -179,18 +180,35 @@ d.Node _section(ReportSection section) {
179180
}
180181

181182
d.Node _downloadsChart(WeeklyVersionDownloadCounts weeklyVersionDownloads) {
183+
final versionModes = d.div(
184+
classes: ['downloads-chart-version-modes'],
185+
children: [
186+
radioButtons(
187+
leadingText: 'By versions: ',
188+
name: 'version-modes',
189+
idsAndValues: [
190+
(id: 'major', value: 'Major'),
191+
(id: 'minor', value: 'Minor'),
192+
(id: 'patch', value: 'Patch')
193+
],
194+
classes: ['downloads-chart-radio-button'],
195+
checkedId: 'major')
196+
],
197+
);
182198
final container = d.div(
183199
classes: ['downloads-chart'],
184200
id: '-downloads-chart',
185201
attributes: {
186202
'data-widget': 'downloads-chart',
187203
'data-downloads-chart-points':
188-
base64Encode(jsonUtf8Encoder.convert(weeklyVersionDownloads))
204+
base64Encode(jsonUtf8Encoder.convert(weeklyVersionDownloads)),
205+
'data-downloads-chart-versions-radio': 'version-modes',
189206
},
190207
);
191208

192209
return d.fragment([
193210
d.h1(text: 'Weekly Downloads over the last 40 weeks'),
211+
versionModes,
194212
container,
195213
]);
196214
}

pkg/web_app/lib/src/widget/downloads_chart/widget.dart

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,19 @@ void create(HTMLElement element, Map<String, String> options) {
3030
throw UnsupportedError('data-downloads-chart-points required');
3131
}
3232

33+
final versionsRadio = options['versions-radio'];
34+
if (versionsRadio == null) {
35+
throw UnsupportedError('data-downloads-chart-versions-radio required');
36+
}
37+
3338
final svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
3439
svg.setAttribute('height', '100%');
3540
svg.setAttribute('width', '100%');
36-
3741
element.append(svg);
42+
3843
final data = WeeklyVersionDownloadCounts.fromJson((utf8.decoder
3944
.fuse(json.decoder)
4045
.convert(base64Decode(dataPoints)) as Map<String, dynamic>));
41-
4246
final weeksToDisplay = math.min(40, data.totalWeeklyDownloads.length);
4347

4448
final majorDisplayLists = prepareWeekLists(
@@ -47,6 +51,34 @@ void create(HTMLElement element, Map<String, String> options) {
4751
weeksToDisplay,
4852
);
4953

54+
final minorDisplayLists = prepareWeekLists(
55+
data.totalWeeklyDownloads,
56+
data.minorRangeWeeklyDownloads,
57+
weeksToDisplay,
58+
);
59+
60+
final patchDisplayLists = prepareWeekLists(
61+
data.totalWeeklyDownloads,
62+
data.patchRangeWeeklyDownloads,
63+
weeksToDisplay,
64+
);
65+
66+
final versionModesLists = {
67+
'Major': majorDisplayLists,
68+
'Minor': minorDisplayLists,
69+
'Patch': patchDisplayLists
70+
};
71+
72+
final versionModes = document.getElementsByName(versionsRadio);
73+
for (int i = 0; i < versionModes.length; i++) {
74+
final radioButton = versionModes.item(i) as HTMLInputElement;
75+
if (versionModesLists[radioButton.value] != null) {
76+
radioButton.onClick.listen((e) {
77+
drawChart(svg, versionModesLists[radioButton.value]!, data.newestDate);
78+
});
79+
}
80+
}
81+
5082
drawChart(svg, majorDisplayLists, data.newestDate);
5183
}
5284

@@ -111,7 +143,7 @@ void drawChart(
111143
}
112144

113145
final chart = SVGGElement();
114-
svg.append(chart);
146+
svg.replaceChildren(chart);
115147

116148
// Axis and ticks
117149

pkg/web_css/lib/src/_pkg.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,14 @@
289289
padding-top: 16px;
290290
}
291291

292+
.downloads-chart-version-modes {
293+
float: right;
294+
}
295+
296+
.downloads-chart-radio-button {
297+
margin-left: 10px;
298+
}
299+
292300
.downloads-chart-frame {
293301
fill:none;
294302
stroke-width: 1;

0 commit comments

Comments
 (0)