Skip to content

Commit 728b20a

Browse files
authored
Downloads chart: show several version modes (#8526)
1 parent a63924c commit 728b20a

File tree

4 files changed

+95
-4
lines changed

4 files changed

+95
-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 label, String value, String id})> radios,
443+
String? initialValue,
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+
radios.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.value == initialValue) 'checked': ''},
461+
));
462+
nodes.add(d.label(attributes: {'for': e.id}, child: d.text(e.label)));
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+
radios: [
190+
(id: 'version-modes-major', value: 'major', label: 'Major'),
191+
(id: 'version-modes-minor', value: 'minor', label: 'Minor'),
192+
(id: 'version-modes-patch', value: 'patch', label: 'Patch')
193+
],
194+
classes: ['downloads-chart-radio-button'],
195+
initialValue: '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: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'package:_pub_shared/data/download_counts_data.dart';
99
import 'package:_pub_shared/format/date_format.dart';
1010
import 'package:_pub_shared/format/number_format.dart';
1111
import 'package:web/web.dart';
12+
import 'package:web_app/src/web_util.dart';
1213

1314
import 'computations.dart';
1415

@@ -30,15 +31,19 @@ void create(HTMLElement element, Map<String, String> options) {
3031
throw UnsupportedError('data-downloads-chart-points required');
3132
}
3233

34+
final versionsRadio = options['versions-radio'];
35+
if (versionsRadio == null) {
36+
throw UnsupportedError('data-downloads-chart-versions-radio required');
37+
}
38+
3339
final svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
3440
svg.setAttribute('height', '100%');
3541
svg.setAttribute('width', '100%');
36-
3742
element.append(svg);
43+
3844
final data = WeeklyVersionDownloadCounts.fromJson((utf8.decoder
3945
.fuse(json.decoder)
4046
.convert(base64Decode(dataPoints)) as Map<String, dynamic>));
41-
4247
final weeksToDisplay = math.min(40, data.totalWeeklyDownloads.length);
4348

4449
final majorDisplayLists = prepareWeekLists(
@@ -47,6 +52,38 @@ void create(HTMLElement element, Map<String, String> options) {
4752
weeksToDisplay,
4853
);
4954

55+
final minorDisplayLists = prepareWeekLists(
56+
data.totalWeeklyDownloads,
57+
data.minorRangeWeeklyDownloads,
58+
weeksToDisplay,
59+
);
60+
61+
final patchDisplayLists = prepareWeekLists(
62+
data.totalWeeklyDownloads,
63+
data.patchRangeWeeklyDownloads,
64+
weeksToDisplay,
65+
);
66+
67+
final versionModesLists = {
68+
'major': majorDisplayLists,
69+
'minor': minorDisplayLists,
70+
'patch': patchDisplayLists
71+
};
72+
73+
final versionModes = document.getElementsByName(versionsRadio).toList();
74+
versionModes.forEach((i) {
75+
final radioButton = i as HTMLInputElement;
76+
final value = radioButton.value;
77+
final displayList = versionModesLists[value];
78+
79+
if (displayList == null) {
80+
throw UnsupportedError('Unsupported versions-radio value: "$value"');
81+
}
82+
radioButton.onClick.listen((e) {
83+
drawChart(svg, displayList, data.newestDate);
84+
});
85+
});
86+
5087
drawChart(svg, majorDisplayLists, data.newestDate);
5188
}
5289

@@ -111,7 +148,7 @@ void drawChart(
111148
}
112149

113150
final chart = SVGGElement();
114-
svg.append(chart);
151+
svg.replaceChildren(chart);
115152

116153
// Axis and ticks
117154

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)