Skip to content

Commit 8a25b50

Browse files
committed
cleanups
1 parent 2c02a13 commit 8a25b50

File tree

5 files changed

+111
-126
lines changed

5 files changed

+111
-126
lines changed

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,7 @@ d.Node _downloadsChart(WeeklyVersionDownloadCounts weeklyVersionDownloads) {
188188
);
189189

190190
return d.fragment([
191-
d.h1(
192-
classes: ['hash-header'],
193-
text: 'Weekly Downloads over the last 40 weeks'),
191+
d.h1(text: 'Weekly Downloads over the last 40 weeks'),
194192
container,
195193
]);
196194
}

pkg/_pub_shared/lib/format/date_format.dart

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,20 @@
55
// Formats a DateTime into abbriviated month and day
66

77
String formatAbbrMonthDay(DateTime date) {
8-
final String month;
9-
switch (date.month) {
10-
case 1:
11-
month = 'Jan';
12-
case 2:
13-
month = 'Feb';
14-
case 3:
15-
month = 'Mar';
16-
case 4:
17-
month = 'Apr';
18-
case 5:
19-
month = 'May';
20-
case 6:
21-
month = 'Jun';
22-
case 7:
23-
month = 'Jul';
24-
case 8:
25-
month = 'Aug';
26-
case 9:
27-
month = 'Sep';
28-
case 10:
29-
month = 'Oct';
30-
case 11:
31-
month = 'Nov';
32-
case 12:
33-
month = 'Dec';
34-
default:
35-
month = '';
36-
}
8+
final month = switch (date.month) {
9+
1 => 'Jan',
10+
2 => 'Feb',
11+
3 => 'Mar',
12+
4 => 'Apr',
13+
5 => 'May',
14+
6 => 'Jun',
15+
7 => 'Jul',
16+
8 => 'Aug',
17+
9 => 'Sep',
18+
10 => 'Oct',
19+
11 => 'Nov',
20+
_ => 'Dec'
21+
};
22+
3723
return '$month ${date.day}';
3824
}

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

Lines changed: 76 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,17 @@ import 'package:web/web.dart';
1212

1313
import 'computations.dart';
1414

15-
const lineColorClasses = [
16-
'downloads-chart-line-color-blue',
17-
'downloads-chart-line-color-red',
18-
'downloads-chart-line-color-green',
19-
'downloads-chart-line-color-purple',
20-
'downloads-chart-line-color-orange',
21-
'downloads-chart-line-color-turquoise',
15+
const colors = [
16+
'blue',
17+
'red',
18+
'green',
19+
'purple',
20+
'orange',
21+
'turquoise',
2222
];
2323

24-
const legendColorClasses = [
25-
'downloads-chart-legend-color-blue',
26-
'downloads-chart-legend-color-red',
27-
'downloads-chart-legend-color-green',
28-
'downloads-chart-legend-color-purple',
29-
'downloads-chart-legend-color-orange',
30-
'downloads-chart-legend-color-turquoise',
31-
];
24+
String strokeColorClass(int i) => 'downloads-chart-stroke-${colors[i]}';
25+
String fillColorClass(int i) => 'downloads-chart-fill-${colors[i]}';
3226

3327
void create(HTMLElement element, Map<String, String> options) {
3428
final dataPoints = options['points'];
@@ -61,11 +55,13 @@ void create(HTMLElement element, Map<String, String> options) {
6155
void drawChart(Element svg, List<String> ranges, List<List<int>> values,
6256
DateTime newestDate,
6357
{bool stacked = false}) {
64-
final width = 775; // TODO(zarah): make this width dynamic
58+
if (values.isEmpty) return;
59+
final frameWidth =
60+
775; // TODO(zarah): Investigate if this width can be dynamic
6561
final topPadding = 30;
6662
final leftPadding = 30;
6763
final rightPadding = 70; // make extra room for labels on y-axis
68-
final drawingWidth = width - leftPadding - rightPadding;
64+
final chartWidth = frameWidth - leftPadding - rightPadding;
6965
final chartheight = 420;
7066

7167
DateTime computeDateForWeekNumber(
@@ -75,7 +71,7 @@ void drawChart(Element svg, List<String> ranges, List<List<int>> values,
7571
}
7672

7773
// Computes max value on y-axis such that we get a nice division for the
78-
// interval length between the numbers shown by the tics on the y axis.
74+
// interval length between the numbers shown by the ticks on the y axis.
7975
(int maxY, int interval) computeMaxYAndInterval(List<List<int>> values) {
8076
final maxDownloads =
8177
values.fold<int>(1, (a, b) => math.max<int>(a, b.reduce(math.max)));
@@ -98,81 +94,85 @@ void drawChart(Element svg, List<String> ranges, List<List<int>> values,
9894

9995
final (maxY, interval) = computeMaxYAndInterval(values);
10096
final firstDate = computeDateForWeekNumber(newestDate, values.length, 0);
97+
final xAxisSpan = newestDate.difference(firstDate);
10198

10299
(double, double) computeCoordinates(DateTime date, int downloads) {
103-
final xAxisSpan = newestDate.difference(firstDate);
104100
final duration = date.difference(firstDate);
101+
// We don't risk division by 0 here, since `xAxisSpan` is a non-zero duration.
105102
final x = leftPadding +
106-
drawingWidth * duration.inMilliseconds / xAxisSpan.inMilliseconds;
103+
chartWidth * duration.inMilliseconds / xAxisSpan.inMilliseconds;
104+
107105
final y = topPadding + (chartheight - chartheight * (downloads / maxY));
108106
return (x, y);
109107
}
110108

111109
final chart = SVGGElement();
112110
svg.append(chart);
113111

114-
// Axis and tics
112+
// Axis and ticks
115113

116114
final (xZero, yZero) = computeCoordinates(firstDate, 0);
117115
final (xMax, yMax) = computeCoordinates(newestDate, maxY);
118116
final lineThickness = 1;
119117
final padding = 8;
120-
final ticLength = 10;
121-
final ticLabelYCoor = yZero + ticLength + 2 * padding;
118+
final labelPadding = 16;
119+
final tickLength = 10;
120+
final tickLabelYCoordinate = yZero + tickLength + labelPadding;
122121

123122
final xaxis = SVGPathElement();
124123
xaxis.setAttribute('class', 'downloads-chart-x-axis');
125124
// We add half of the line thickness at both ends of the x-axis so that it
126-
// covers the vertical tics at the end.
125+
// covers the vertical ticks at the end.
127126
xaxis.setAttribute('d',
128127
'M${xZero - (lineThickness / 2)} $yZero L${xMax + (lineThickness / 2)} $yZero');
129128
chart.append(xaxis);
130129

131-
var firstTicLabel = SVGTextElement();
130+
late SVGTextElement firstTickLabel;
131+
// place a tick every 4 weeks
132132
for (int week = 0; week < values.length; week += 4) {
133133
final date = computeDateForWeekNumber(newestDate, values.length, week);
134134
final (x, y) = computeCoordinates(date, 0);
135135

136-
final tic = SVGPathElement();
137-
tic.setAttribute('class', 'downloads-chart-x-axis');
138-
tic.setAttribute('d', 'M$x $y l0 $ticLength');
139-
chart.append(tic);
136+
final tick = SVGPathElement();
137+
tick.setAttribute('class', 'downloads-chart-x-axis');
138+
tick.setAttribute('d', 'M$x $y l0 $tickLength');
139+
chart.append(tick);
140140

141-
final ticLabel = SVGTextElement();
142-
chart.append(ticLabel);
143-
ticLabel.setAttribute(
144-
'class', 'downloads-chart-tic-label downloads-chart-tic-label-x');
145-
ticLabel.text = formatAbbrMonthDay(date);
146-
ticLabel.setAttribute('y', '$ticLabelYCoor');
147-
ticLabel.setAttribute('x', '$x');
141+
final tickLabel = SVGTextElement();
142+
chart.append(tickLabel);
143+
tickLabel.setAttribute(
144+
'class', 'downloads-chart-tick-label downloads-chart-tick-label-x');
145+
tickLabel.text = formatAbbrMonthDay(date);
146+
tickLabel.setAttribute('y', '$tickLabelYCoordinate');
147+
tickLabel.setAttribute('x', '$x');
148148

149149
if (week == 0) {
150-
firstTicLabel = ticLabel;
150+
firstTickLabel = tickLabel;
151151
}
152152
}
153153

154154
for (int i = 0; i <= maxY / interval; i++) {
155155
final (x, y) = computeCoordinates(firstDate, i * interval);
156156

157-
final ticLabel = SVGTextElement();
158-
ticLabel.setAttribute(
159-
'class', 'downloads-chart-tic-label downloads-chart-tic-label-y');
160-
ticLabel.text =
157+
final tickLabel = SVGTextElement();
158+
tickLabel.setAttribute(
159+
'class', 'downloads-chart-tick-label downloads-chart-tick-label-y');
160+
tickLabel.text =
161161
'${compactFormat(i * interval).value}${compactFormat(i * interval).suffix}';
162-
ticLabel.setAttribute('x', '${xMax + padding}');
163-
ticLabel.setAttribute('y', '$y');
164-
chart.append(ticLabel);
162+
tickLabel.setAttribute('x', '${xMax + padding}');
163+
tickLabel.setAttribute('y', '$y');
164+
chart.append(tickLabel);
165165

166166
if (i == 0) {
167-
// No long tic in the bottom, we have the x-axis here.
167+
// No long tick in the bottom, we have the x-axis here.
168168
continue;
169169
}
170170

171-
final longTic = SVGPathElement();
172-
longTic.setAttribute('class', 'downloads-chart-frame');
173-
longTic.setAttribute('d',
171+
final longTick = SVGPathElement();
172+
longTick.setAttribute('class', 'downloads-chart-frame');
173+
longTick.setAttribute('d',
174174
'M${xZero - (lineThickness / 2)} $y L${xMax - (lineThickness / 2)} $y');
175-
chart.append(longTic);
175+
chart.append(longTick);
176176
}
177177

178178
// We use the clipPath to cut the ends of the chart lines so that we don't
@@ -182,8 +182,8 @@ void drawChart(Element svg, List<String> ranges, List<List<int>> values,
182182
final clipRect = SVGRectElement();
183183
clipRect.setAttribute('y', '$yMax');
184184
clipRect.setAttribute('height', '${chartheight - (lineThickness / 2)}');
185-
clipRect.setAttribute('x', '${xZero - (lineThickness / 2)}');
186-
clipRect.setAttribute('width', '${drawingWidth + lineThickness}');
185+
clipRect.setAttribute('x', '$xZero');
186+
clipRect.setAttribute('width', '$chartWidth');
187187
clipPath.append(clipRect);
188188
chart.append(clipPath);
189189

@@ -203,59 +203,63 @@ void drawChart(Element svg, List<String> ranges, List<List<int>> values,
203203
lines.add(line);
204204
}
205205

206-
double legendXCoor = xZero - firstTicLabel.getBBox().width / 2;
206+
double legendXCoor = xZero;
207207
double legendYCoor =
208-
ticLabelYCoor + firstTicLabel.getBBox().height + 2 * padding;
208+
tickLabelYCoordinate + firstTickLabel.getBBox().height + labelPadding;
209209
final legendWidth = 20;
210210
final legendHeight = 8;
211211

212-
for (int j = 0; j < lines.length; j++) {
212+
for (int i = 0; i < lines.length; i++) {
213213
final path = SVGPathElement();
214-
path.setAttribute('class', '${lineColorClasses[j]} downloads-chart-line ');
215-
// We assign colors in revers order so that main colors are chosen first for
214+
path.setAttribute('class', '${strokeColorClass(i)} downloads-chart-line ');
215+
// We assign colors in reverse order so that main colors are chosen first for
216216
// the newest versions.
217-
path.setAttribute('d', '${lines[lines.length - 1 - j]}');
217+
path.setAttribute('d', '${lines[lines.length - 1 - i]}');
218218
path.setAttribute('clip-path', 'url(#clipRect)');
219219
chart.append(path);
220220

221221
final legend = SVGRectElement();
222222
chart.append(legend);
223-
legend.setAttribute(
224-
'class', 'downloads-chart-legend ${legendColorClasses[j]}');
223+
legend.setAttribute('class',
224+
'downloads-chart-legend ${fillColorClass(i)} ${strokeColorClass(i)}');
225225
legend.setAttribute('height', '$legendHeight');
226226
legend.setAttribute('width', '$legendWidth');
227227

228228
final legendLabel = SVGTextElement();
229229
chart.append(legendLabel);
230-
legendLabel.setAttribute(
231-
'class', 'downloads-chart-tic-label downloads-chart-tic-label-y');
232-
legendLabel.text = ranges[j];
230+
legendLabel.setAttribute('class', 'downloads-chart-tick-label');
231+
if (i == 5) {
232+
// We have an 'other' line
233+
legendLabel.text = 'Other';
234+
} else {
235+
legendLabel.text = ranges[ranges.length - 1 - i];
236+
}
233237

234238
if (legendXCoor + padding + legendWidth + legendLabel.getBBox().width >
235239
xMax) {
236240
// There is no room for the legend and label.
237241
// Make a new line and update legendXCoor and legendYCoor accordingly.
238242

239-
legendXCoor = xZero - firstTicLabel.getBBox().width / 2;
243+
legendXCoor = xZero;
240244
legendYCoor += 2 * padding + legendHeight;
241245
}
242246

243247
legend.setAttribute('x', '$legendXCoor');
244248
legend.setAttribute('y', '$legendYCoor');
245-
legendLabel.setAttribute('y', '${legendYCoor + legendHeight / 2}');
249+
legendLabel.setAttribute('y', '${legendYCoor + legendHeight}');
246250
legendLabel.setAttribute('x', '${legendXCoor + padding + legendWidth}');
247251

248252
// Update x coordinate for next legend
249253
legendXCoor +=
250-
legendWidth + padding + legendLabel.getBBox().width + 2 * padding;
254+
legendWidth + padding + legendLabel.getBBox().width + labelPadding;
251255
}
252256

253-
final height = legendYCoor + 3 * padding;
254-
final frame = SVGRectElement();
257+
final frameHeight = legendYCoor + padding + labelPadding;
258+
final frame = SVGRectElement()
259+
..setAttribute('class', 'downloads-chart-frame')
260+
..setAttribute('height', '$frameHeight')
261+
..setAttribute('width', '$frameWidth')
262+
..setAttribute('rx', '15')
263+
..setAttribute('ry', '15');
255264
chart.append(frame);
256-
frame.setAttribute('height', '$height');
257-
frame.setAttribute('width', '$width');
258-
frame.setAttribute('rx', '15');
259-
frame.setAttribute('ry', '15');
260-
frame.setAttribute('class', 'downloads-chart-frame');
261265
}

0 commit comments

Comments
 (0)