Skip to content

Commit b5f7154

Browse files
authored
Downloads chart: resize chart on screen size changes (#8576)
1 parent a0c4ca1 commit b5f7154

File tree

6 files changed

+126
-44
lines changed

6 files changed

+126
-44
lines changed

app/lib/frontend/dom/material.dart

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -449,18 +449,17 @@ d.Node radioButtons({
449449
nodes.add(d.strong(text: leadingText));
450450
}
451451
radios.forEach((e) {
452-
nodes.add(d.input(
452+
final button = (d.input(
453453
id: e.id,
454454
type: 'radio',
455455
name: name,
456456
value: e.value,
457-
classes: [
458-
...?classes,
459-
],
460457
attributes: {if (e.value == initialValue) 'checked': ''},
461458
));
462-
nodes.add(d.label(attributes: {'for': e.id}, child: d.text(e.label)));
459+
final label = d.label(attributes: {'for': e.id}, child: d.text(e.label));
460+
final div = d.div(children: [button, label]);
461+
nodes.add(div);
463462
});
464463

465-
return d.div(classes: ['mdc-form-field'], children: nodes);
464+
return d.div(classes: ['mdc-form-field', ...?classes], children: nodes);
466465
}

app/test/frontend/golden/pkg_score_page.html

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -308,25 +308,37 @@ <h3>
308308
</p>
309309
<h1>Weekly downloads</h1>
310310
<div class="downloads-chart-display-modes">
311-
<div class="mdc-form-field">
311+
<div class="mdc-form-field downloads-chart-radio-button">
312312
<strong>Display as:</strong>
313-
<input id="display-modes-unstacked" class="downloads-chart-radio-button" type="radio" name="display-modes" value="unstacked" checked=""/>
314-
<label for="display-modes-unstacked">Unstacked</label>
315-
<input id="version-modes-stacked" class="downloads-chart-radio-button" type="radio" name="display-modes" value="stacked"/>
316-
<label for="version-modes-stacked">Stacked</label>
317-
<input id="version-modes-percentage" class="downloads-chart-radio-button" type="radio" name="display-modes" value="percentage"/>
318-
<label for="version-modes-percentage">Percentage</label>
313+
<div>
314+
<input id="display-modes-unstacked" type="radio" name="display-modes" value="unstacked" checked=""/>
315+
<label for="display-modes-unstacked">Unstacked</label>
316+
</div>
317+
<div>
318+
<input id="version-modes-stacked" type="radio" name="display-modes" value="stacked"/>
319+
<label for="version-modes-stacked">Stacked</label>
320+
</div>
321+
<div>
322+
<input id="version-modes-percentage" type="radio" name="display-modes" value="percentage"/>
323+
<label for="version-modes-percentage">Percentage</label>
324+
</div>
319325
</div>
320326
</div>
321327
<div class="downloads-chart-version-modes">
322-
<div class="mdc-form-field">
328+
<div class="mdc-form-field downloads-chart-radio-button">
323329
<strong>By versions:</strong>
324-
<input id="version-modes-major" class="downloads-chart-radio-button" type="radio" name="version-modes" value="major" checked=""/>
325-
<label for="version-modes-major">Major</label>
326-
<input id="version-modes-minor" class="downloads-chart-radio-button" type="radio" name="version-modes" value="minor"/>
327-
<label for="version-modes-minor">Minor</label>
328-
<input id="version-modes-patch" class="downloads-chart-radio-button" type="radio" name="version-modes" value="patch"/>
329-
<label for="version-modes-patch">Patch</label>
330+
<div>
331+
<input id="version-modes-major" type="radio" name="version-modes" value="major" checked=""/>
332+
<label for="version-modes-major">Major</label>
333+
</div>
334+
<div>
335+
<input id="version-modes-minor" type="radio" name="version-modes" value="minor"/>
336+
<label for="version-modes-minor">Minor</label>
337+
</div>
338+
<div>
339+
<input id="version-modes-patch" type="radio" name="version-modes" value="patch"/>
340+
<label for="version-modes-patch">Patch</label>
341+
</div>
330342
</div>
331343
</div>
332344
<div id="-downloads-chart" class="downloads-chart" data-widget="downloads-chart" data-downloads-chart-points="%%downloads-chart-points%%" data-downloads-chart-versions-radio="version-modes" data-downloads-chart-display-radio="display-modes"></div>

app/test/frontend/golden/pkg_score_page_with_downloads_chart.html

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -308,25 +308,37 @@ <h3>
308308
</p>
309309
<h1>Weekly downloads</h1>
310310
<div class="downloads-chart-display-modes">
311-
<div class="mdc-form-field">
311+
<div class="mdc-form-field downloads-chart-radio-button">
312312
<strong>Display as:</strong>
313-
<input id="display-modes-unstacked" class="downloads-chart-radio-button" type="radio" name="display-modes" value="unstacked" checked=""/>
314-
<label for="display-modes-unstacked">Unstacked</label>
315-
<input id="version-modes-stacked" class="downloads-chart-radio-button" type="radio" name="display-modes" value="stacked"/>
316-
<label for="version-modes-stacked">Stacked</label>
317-
<input id="version-modes-percentage" class="downloads-chart-radio-button" type="radio" name="display-modes" value="percentage"/>
318-
<label for="version-modes-percentage">Percentage</label>
313+
<div>
314+
<input id="display-modes-unstacked" type="radio" name="display-modes" value="unstacked" checked=""/>
315+
<label for="display-modes-unstacked">Unstacked</label>
316+
</div>
317+
<div>
318+
<input id="version-modes-stacked" type="radio" name="display-modes" value="stacked"/>
319+
<label for="version-modes-stacked">Stacked</label>
320+
</div>
321+
<div>
322+
<input id="version-modes-percentage" type="radio" name="display-modes" value="percentage"/>
323+
<label for="version-modes-percentage">Percentage</label>
324+
</div>
319325
</div>
320326
</div>
321327
<div class="downloads-chart-version-modes">
322-
<div class="mdc-form-field">
328+
<div class="mdc-form-field downloads-chart-radio-button">
323329
<strong>By versions:</strong>
324-
<input id="version-modes-major" class="downloads-chart-radio-button" type="radio" name="version-modes" value="major" checked=""/>
325-
<label for="version-modes-major">Major</label>
326-
<input id="version-modes-minor" class="downloads-chart-radio-button" type="radio" name="version-modes" value="minor"/>
327-
<label for="version-modes-minor">Minor</label>
328-
<input id="version-modes-patch" class="downloads-chart-radio-button" type="radio" name="version-modes" value="patch"/>
329-
<label for="version-modes-patch">Patch</label>
330+
<div>
331+
<input id="version-modes-major" type="radio" name="version-modes" value="major" checked=""/>
332+
<label for="version-modes-major">Major</label>
333+
</div>
334+
<div>
335+
<input id="version-modes-minor" type="radio" name="version-modes" value="minor"/>
336+
<label for="version-modes-minor">Minor</label>
337+
</div>
338+
<div>
339+
<input id="version-modes-patch" type="radio" name="version-modes" value="patch"/>
340+
<label for="version-modes-patch">Patch</label>
341+
</div>
330342
</div>
331343
</div>
332344
<div id="-downloads-chart" class="downloads-chart" data-widget="downloads-chart" data-downloads-chart-points="%%downloads-chart-points%%" data-downloads-chart-versions-radio="version-modes" data-downloads-chart-display-radio="display-modes"></div>

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

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'dart:convert';
6+
import 'dart:js_interop';
67
import 'dart:math' as math;
78

89
import 'package:_pub_shared/data/download_counts_data.dart';
@@ -111,6 +112,7 @@ void create(HTMLElement element, Map<String, String> options) {
111112
currentDisplayList = displayList;
112113
drawChart(
113114
svg,
115+
svg.getBoundingClientRect().width,
114116
toolTip,
115117
displayList,
116118
data.newestDate,
@@ -143,6 +145,7 @@ void create(HTMLElement element, Map<String, String> options) {
143145
currentDisplayMode = displayMode;
144146
drawChart(
145147
svg,
148+
svg.getBoundingClientRect().width,
146149
toolTip,
147150
currentDisplayList,
148151
data.newestDate,
@@ -152,17 +155,41 @@ void create(HTMLElement element, Map<String, String> options) {
152155
});
153156
});
154157

158+
void resize(double width) {
159+
element.removeChild(svg);
160+
svg = createNewSvg();
161+
element.append(svg);
162+
163+
drawChart(
164+
svg,
165+
width,
166+
toolTip,
167+
currentDisplayList,
168+
data.newestDate,
169+
totals,
170+
);
171+
}
172+
173+
final resizeObserver = ResizeObserver(
174+
(JSArray<ResizeObserverEntry> a, ResizeObserverBoxOptions b) {
175+
resize(a.toDart[0].contentRect.width);
176+
}.toJS);
177+
155178
drawChart(
156179
svg,
180+
svg.getBoundingClientRect().width,
157181
toolTip,
158-
majorDisplayLists,
182+
currentDisplayList,
159183
data.newestDate,
160184
totals,
161185
);
186+
187+
resizeObserver.observe(element);
162188
}
163189

164190
void drawChart(
165191
Element svg,
192+
double width,
166193
HTMLDivElement toolTip,
167194
({List<String> ranges, List<List<int>> weekLists}) displayLists,
168195
DateTime newestDate,
@@ -173,8 +200,7 @@ void drawChart(
173200

174201
if (values.isEmpty) return;
175202

176-
final frameWidth =
177-
775; // TODO(zarah): Investigate if this width can be dynamic
203+
final frameWidth = width;
178204
final topPadding = 30;
179205
final leftPadding = 30;
180206
final rightPadding = 70; // Make extra room for labels on y-axis
@@ -266,8 +292,15 @@ void drawChart(
266292

267293
final tickLabel = SVGTextElement();
268294
chart.append(tickLabel);
269-
tickLabel.setAttribute(
270-
'class', 'downloads-chart-tick-label downloads-chart-tick-label-x');
295+
296+
if (week % 8 == 0) {
297+
// We skip every other label on small screens.
298+
tickLabel.setAttribute('class',
299+
'downloads-chart-tick-label downloads-chart-anchored-tick-label-x');
300+
} else {
301+
tickLabel.setAttribute(
302+
'class', 'downloads-chart-tick-label downloads-chart-tick-label-x');
303+
}
271304
tickLabel.text = formatAbbrMonthDay(date);
272305
tickLabel.setAttribute('y', '$tickLabelYCoordinate');
273306
tickLabel.setAttribute('x', '$x');
@@ -460,12 +493,15 @@ void drawChart(
460493
}
461494

462495
cursor.setAttribute('style', 'opacity:1');
463-
toolTip.setAttribute(
464-
'style',
465-
'top:${e.y + toolTipOffsetFromMouse + document.scrollingElement!.scrollTop}px;'
466-
'left:${e.x}px;');
467496

468497
final pointPercentage = (e.x - boundingRect.x - xZero) / chartWidth;
498+
final horizontalPosition =
499+
e.x + toolTip.getBoundingClientRect().width > width
500+
? 'left:${e.x - toolTip.getBoundingClientRect().width}px;'
501+
: 'left:${e.x}px;';
502+
toolTip.setAttribute('style',
503+
'top:${e.y + toolTipOffsetFromMouse + document.scrollingElement!.scrollTop}px;$horizontalPosition');
504+
469505
final nearestIndex = ((values.length - 1) * pointPercentage).round();
470506
final selectedDay =
471507
computeDateForWeekNumber(newestDate, values.length, nearestIndex);

pkg/web_css/lib/src/_pkg.scss

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,21 +279,32 @@
279279
.downloads-chart {
280280
display: flex;
281281
height: 700px;
282-
width: 775px;
282+
width: 100%;
283283
flex-direction: column;
284284
margin-top: 16px;
285285
}
286286

287287
.downloads-chart-version-modes {
288288
float: right;
289+
290+
@media (max-width: variables.$downloads-chart-display-max-width) {
291+
float: left;
292+
}
289293
}
290294

291295
.downloads-chart-display-modes {
292296
float: left;
293297
}
294298

295299
.downloads-chart-radio-button {
300+
display: flex;
301+
flex-direction: row;
296302
margin-left: 10px;
303+
304+
@media (max-width: variables.$downloads-chart-radio-max-width) {
305+
display: flex;
306+
flex-direction: column;
307+
}
297308
}
298309

299310
.downloads-chart-axis-line {
@@ -358,6 +369,14 @@
358369

359370
.downloads-chart-tick-label-x {
360371
text-anchor: middle;
372+
@media (max-width: variables.$downloads-chart-label-max-width) {
373+
display: none;
374+
}
375+
}
376+
377+
// These labels are not removed even if the screen gets smaller.
378+
.downloads-chart-anchored-tick-label-x {
379+
text-anchor: middle;
361380
}
362381

363382
.downloads-chart-tick-label-y {

pkg/web_css/lib/src/_variables.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,10 @@ $device-desktop-min-width: 641px;
301301
$device-mobile-max-width: 640px;
302302
$device-tablet-max-width: 979px;
303303

304+
$downloads-chart-label-max-width: 825px;
305+
$downloads-chart-display-max-width: 1025px;
306+
$downloads-chart-radio-max-width: 650px;
307+
304308
$z-index-nav-mask: 1000;
305309

306310
$site-max-width: 1136px;

0 commit comments

Comments
 (0)