Skip to content

Commit

Permalink
Bugfixes and minor improvements (#858)
Browse files Browse the repository at this point in the history
* fix incomplete techs bug

* sort filterts alphabetically

* keep ALL as a technology option

* show all technologies when choosing all categories

* revert sort order and add fallback for selected techs

* scroll to the report content when clicking update (#851)

* show formatted page weight

* format tooltip with correct timezone

* format pageweight in summary view

* change feedback url and style beta label differently

* linting

* fix inverted color bug

* replace dev with prod API

* remove placeholder images

* Update src/js/techreport/utils/data.js

Co-authored-by: Rick Viscomi <[email protected]>

* remove secondary value

* remove bytes from weight timeseries and move formatting to reusable function

* innerhtml to textcontent

---------

Co-authored-by: Rick Viscomi <[email protected]>
sarahfossheim and rviscomi authored May 31, 2024
1 parent 9edc219 commit d337ba9
Showing 11 changed files with 199 additions and 58 deletions.
47 changes: 23 additions & 24 deletions config/techreport.json
Original file line number Diff line number Diff line change
@@ -115,11 +115,10 @@
"url": "#lighthouse&median-lighthouse-over-time=accessibility"
},
{
"endpoint": "lighthouse",
"category": "seo",
"metric": "median_score_pct",
"endpoint": "pageWeight",
"category": "total",
"metric": "median_bytes_formatted",
"label": "Page weight",
"suffix": "kB",
"description": "Median total bytes per page for across tested origins.",
"url": "#page-weight"
}
@@ -525,26 +524,23 @@
{
"endpoint": "pageWeight",
"category": "images",
"metric": "median_bytes",
"metric": "median_bytes_formatted",
"label": "Image Weight",
"url": "?weight-over-time=image#page-weight",
"suffix": " kB"
"url": "?weight-over-time=image#page-weight"
},
{
"endpoint": "pageWeight",
"category": "js",
"metric": "median_bytes",
"metric": "median_bytes_formatted",
"label": "JavaScript Size",
"url": "?weight-over-time=js#page-weight",
"suffix": " kB"
"url": "?weight-over-time=js#page-weight"
},
{
"endpoint": "pageWeight",
"category": "total",
"metric": "median_bytes",
"metric": "median_bytes_formatted",
"label": "Total Page Weight",
"url": "?weight-over-time=total#page-weight",
"suffix": " kB"
"url": "?weight-over-time=total#page-weight"
}
]
},
@@ -586,8 +582,7 @@
},
{
"name": "Median Bytes",
"key": "median_bytes",
"suffix": "kB",
"key": "median_bytes_formatted",
"className": "main-cell"
},
{
@@ -603,19 +598,21 @@
"default": "images",
"title": "Image weight over time",
"metric": "median_bytes",
"suffix": "bytes",
"metric_summary": "median_bytes_formatted",
"height": 600,
"series": {
"breakdown": "client",
"values": [
{
"name": "desktop",
"color": "#669E8E",
"suffix": " kB"
"suffix": " bytes"
},
{
"name": "mobile",
"color": "#BD6EBE",
"suffix": " kB"
"suffix": " bytes"
}
],
"defaults": [
@@ -648,7 +645,7 @@
]
},
"yAxis": {
"title": "Weight in kB"
"title": "Weight in bytes"
}
}
}
@@ -978,8 +975,7 @@
},
{
"name": "Median Bytes",
"key": "median_bytes",
"suffix": "kB",
"key": "median_bytes_formatted",
"className": "main-cell",
"breakdown": "app"
},
@@ -997,17 +993,20 @@
"param": "median-weight-over-time",
"default": "total",
"metric": "median_bytes",
"metric_summary": "median_bytes_formatted",
"series": {
"breakdown": "app",
"suffix": " kB",
"suffix": " bytes",
"defaults": [
{
"name": "App",
"data": [0,0,0,0,0,0,0,0,0,0,0,0]
"data": [0,0,0,0,0,0,0,0,0,0,0,0],
"suffix": " bytes"
},
{
"name": "App",
"data": [0,0,0,0,0,0,0,0,0,0,0,0]
"data": [0,0,0,0,0,0,0,0,0,0,0,0],
"suffix": " bytes"
}
]
},
@@ -1030,7 +1029,7 @@
]
},
"yAxis": {
"title": "Weight in kB"
"title": "Weight in bytes"
}
}
},
2 changes: 2 additions & 0 deletions server/csp.py
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
"lux.speedcurve.com",
"'unsafe-inline'",
"dev-gw-2vzgiib6.ue.gateway.dev",
"prod-gw-2vzgiib6.ue.gateway.dev",
],
"font-src": ["'self'"],
"connect-src": [
@@ -26,6 +27,7 @@
"*.analytics.google.com",
"stats.g.doubleclick.net",
"dev-gw-2vzgiib6.ue.gateway.dev",
"prod-gw-2vzgiib6.ue.gateway.dev",
],
"img-src": ["'self'", "https:"],
"frame-src": ["'none'"],
2 changes: 2 additions & 0 deletions src/js/components/filters.js
Original file line number Diff line number Diff line change
@@ -63,6 +63,8 @@ class Filters {
url.searchParams.delete('rank');
url.searchParams.append('rank', rank);

/* Scroll to the report content */
url.hash = '#report-content';

/* Update the url */
location.href = url;
4 changes: 2 additions & 2 deletions src/js/techreport/index.js
Original file line number Diff line number Diff line change
@@ -174,7 +174,7 @@ class TechReport {
},
];

const base = 'https://dev-gw-2vzgiib6.ue.gateway.dev/v1';
const base = 'https://prod-gw-2vzgiib6.ue.gateway.dev/v1';

const technology = technologies.join('%2C')
.replaceAll(" ", "%20");
@@ -239,7 +239,7 @@ class TechReport {
// Fetch the data for the filter dropdowns
getFilterInfo() {
const filterData = {};
const base = 'https://dev-gw-2vzgiib6.ue.gateway.dev/v1';
const base = 'https://prod-gw-2vzgiib6.ue.gateway.dev/v1';

const filterApis = ['categories', 'technologies', 'ranks', 'geos'];

132 changes: 119 additions & 13 deletions src/js/techreport/timeseries.js
Original file line number Diff line number Diff line change
@@ -49,10 +49,10 @@ class Timeseries {
const button = event.target;
const tableWrapper = document.getElementById(`${button.dataset.id}-table-wrapper`);
if(tableWrapper.classList.contains('hidden')) {
button.innerHTML = 'Hide table';
button.textContent = 'Hide table';
tableWrapper.classList.remove('hidden');
} else {
button.innerHTML = 'Show table';
button.textContent = 'Show table';
tableWrapper.classList.add('hidden');
}
}
@@ -108,6 +108,7 @@ class Timeseries {
/* Get settings */
const metric = viz.dataset.metric;
const endpoint = viz.dataset.endpoint;
const summary = viz.dataset.summary;

const app = pageFilters.app[0];
const filtered = data?.[app]?.filter(entry => entry[endpoint]);
@@ -143,11 +144,19 @@ class Timeseries {
breakdownLabel.classList.add('breakdown-label');
itemWrapper.appendChild(breakdownLabel);

/* Add the value to the wrapper */
const valueLabel = document.createElement('p');
valueLabel.textContent = `${latestValue}${breakdown.suffix || ''}`;
valueLabel.classList.add('breakdown-value');
itemWrapper.appendChild(valueLabel);
/* If defined, use a different metric for the summary */
if(summary) {
const valueLabel = document.createElement('p');
valueLabel.textContent = categoryData?.[breakdown.name]?.[summary];
valueLabel.classList.add('breakdown-value');
itemWrapper.appendChild(valueLabel);
} else {
/* Add the value to the wrapper */
const valueLabel = document.createElement('p');
valueLabel.textContent = `${latestValue}${breakdown.suffix || ''}`;
valueLabel.classList.add('breakdown-value');
itemWrapper.appendChild(valueLabel);
}

/* Add the wrapper to the container */
container.appendChild(itemWrapper);
@@ -173,6 +182,7 @@ class Timeseries {
const metric = component.dataset.metric;
const endpoint = component.dataset.endpoint;
const client = component.dataset.client;
const summary = component.dataset.summary;

pageFilters.app.forEach((app, index) => {
if(data[app] && data[app].length > 0) {
@@ -184,6 +194,7 @@ class Timeseries {
const latestSubcategory = latestEndpoint?.find(row => row.name === subcategory);
const latestClient = latestSubcategory?.[client];
const latestValue = latestClient?.[metric];
const summaryValue = latestClient?.[summary];

/* Select the container to which we'll add elements. */
const card = container.querySelector(`[data-app="${app}"]`);
@@ -192,14 +203,18 @@ class Timeseries {
const value = card.getElementsByClassName('breakdown-value')[0];

/* Update text */
label.innerHTML = latest.technology;
label.textContent = latest.technology;
if(latestValue) {
value.innerHTML = `${latestValue}${config.series.suffix || ''}`;
if(summary) {
value.textContent = `${summaryValue}`;
} else {
value.textContent = `${latestValue}${config.series.suffix || ''}`;
}
} else {
value.classList.add('undefined');
value.innerHTML = 'No data';
value.textContent = 'No data';
}
timestamp.innerHTML = latest.date;
timestamp.textContent = latest.date;
const techColor = UIUtils.getAppColor(app, this.pageFilters.app, this.pageConfig.colors);
const fallback = this.pageConfig.colors.app[index];
card.style.setProperty('--breakdown-color', techColor || fallback);
@@ -248,6 +263,97 @@ class Timeseries {
timeseries.series = this.formatSeries();
}

timeseries.tooltip = {
shared: true,
crosshairs: true,
useHTML: true,
formatter: function() {
const wrapper = document.createElement('div');
wrapper.className = 'tooltip-wrapper';

const d = Highcharts.dateFormat('%b %e, %Y', this.x);

const dateEl = document.createElement('p');
dateEl.innerHTML = d;

wrapper.appendChild(dateEl);

const pointList = document.createElement('ul');

this.points.forEach(point => {
const pointItem = document.createElement('li');
const pointSeries = document.createElement('span');

const pointSvg = document.createElement('svg');
let pointSymbol;


switch(point?.point?.graphic?.symbolName) {
case 'circle':
pointSymbol = document.createElement('circle');
pointSymbol.setAttribute('class', 'point-symbol circle');
pointSymbol.setAttribute('r', point.point.graphic.width / 2);
pointSymbol.setAttribute('stroke', point.color);
pointSymbol.setAttribute('stroke-width', point.point.graphic['stroke-width']);
break;

case 'diamond':
pointSymbol = document.createElement('path');
pointSymbol.setAttribute('class', 'point-symbol diamond');
pointSymbol.setAttribute('d', 'M 4 0 L 8 4 L 4 8 L 0 4 Z');
pointSymbol.setAttribute('stroke', point.color);
pointSymbol.setAttribute('stroke-width', point.point.graphic['stroke-width']);
break;

case 'square':
pointSymbol = document.createElement('path');
pointSymbol.setAttribute('class', 'point-symbol square');
pointSymbol.setAttribute('d', 'M 0 0 L 8 0 L 8 8 L 0 8 Z');
pointSymbol.setAttribute('stroke', point.color);
pointSymbol.setAttribute('stroke-width', point.point.graphic['stroke-width']);
break;

case 'triangle-down':
pointSymbol = document.createElement('path');
pointSymbol.setAttribute('class', 'point-symbol triangle-down');
pointSymbol.setAttribute('d', 'M 0 0 L 8 0 L 4 8 Z');
pointSymbol.setAttribute('stroke', point.color);
pointSymbol.setAttribute('stroke-width', point.point.graphic['stroke-width']);
break;

case 'triangle':
pointSymbol = document.createElement('path');
pointSymbol.setAttribute('class', 'point-symbol triangle-up');
pointSymbol.setAttribute('d', 'M 4 0 L 8 8 L 0 8 Z');
pointSymbol.setAttribute('stroke', point.color);
pointSymbol.setAttribute('stroke-width', point.point.graphic['stroke-width']);
break;


default:
pointSymbol = document.createElement('circle');
pointSymbol.setAttribute('class', 'point-fallback');
pointSymbol.setAttribute('r', '4');
pointSymbol.setAttribute('fill', point.color);
break;
}

pointSvg.appendChild(pointSymbol);

document.getElementsByTagName('main')[0].append(pointSvg);

pointSeries.innerHTML = point.series.name;
pointItem.innerHTML = `${pointSvg.outerHTML} ${pointSeries.outerHTML}: ${point.y}`;

pointList.appendChild(pointItem);
});

wrapper.appendChild(pointList);

return wrapper.outerHTML;
}
}

// Render the chart
Highcharts.chart(`${this.id}-timeseries`, timeseries);
}
@@ -298,7 +404,7 @@ class Timeseries {
const data = app.map(row => {
const value = row?.[endpoint]?.find(row => row.name === subcategory)?.[client]?.[metric];
return {
x: new Date(row.date),
x: new Date(row.date).getTime(),
y: value || 0,
};
});
@@ -341,7 +447,7 @@ class Timeseries {
const clientData = categoryData?.[value.name];
const y = clientData?.[metric];
formattedData.push({
x: new Date(row.date),
x: new Date(row.date).getTime(),
y: Number(y),
});
});
6 changes: 6 additions & 0 deletions src/js/techreport/utils/data.js
Original file line number Diff line number Diff line change
@@ -56,17 +56,23 @@ const parseAdoptionData = (submetric, date) => {
];
}

const formatBytes = (value) => {
return value > 1048576 ? `${Math.round(value / 1048576)} MB` : value > 1024 ? `${Math.round(value / 1024)} KB` : `${submetric.desktop.median_bytes} bytes`;
};

const parsePageWeightData = (metric, date) => {
return metric.map(submetric => {
return {
...submetric,
desktop: {
...submetric.desktop,
median_bytes_formatted: formatBytes(submetric.desktop.median_bytes),
client: 'desktop',
date: date,
},
mobile: {
...submetric.mobile,
median_bytes_formatted: formatBytes(submetric.mobile.median_bytes),
client: 'mobile',
date: date,
},
8 changes: 0 additions & 8 deletions static/css/techreport/landing.css
Original file line number Diff line number Diff line change
@@ -25,14 +25,6 @@
padding: 0;
}

.choices .card .img-placeholder {
display: block;
width: 100%;
height: 17rem;
background-color: #eee;
margin-top: 1rem;
}

.latest-info h2 {
font-size: 1rem;
font-weight: 600;
48 changes: 42 additions & 6 deletions static/css/techreport/techreport.css
Original file line number Diff line number Diff line change
@@ -433,6 +433,11 @@ main :is(a, p a) {
color: var(--color-text);
}

[data-theme="dark"] select option,
[data-theme="dark"] .tech-input-wrapper:has(select:focus-visible) select {
color: var(--color-page-background) !important;
}

.tech-selector-group .content {
position: relative;
width: 100%;
@@ -697,11 +702,9 @@ select {
}

.info-panel .info-label {
margin-right: 1rem;
padding: 0.3rem 0.5rem;
border-radius: 3px;
background-color: white;
border: 1px solid black;
margin-right: 0.75rem;
margin-left: 0.25rem;
font-weight: 600;
}

/* General tables */
@@ -1134,12 +1137,45 @@ path.highcharts-tick {
filter: none;
}

.highcharts-tooltip path {
.highcharts-tooltip > path {
fill: var(--color-tooltip-background);
stroke: var(--color-tooltip-border);
stroke-width: 1px;
}

.tooltip-wrapper ul {
margin-top: 0.5rem;
}

.tooltip-wrapper li {
position: relative;
}

.tooltip-wrapper li span {
font-weight: 600;
}

.tooltip-wrapper li svg {
position: relative;
left: 0;
top: 0.05rem;
width: 0.75rem;
height: 0.75rem;
}

.tooltip-wrapper svg .point-symbol {
fill: var(--color-card-background);
}

.tooltip-wrapper svg .point-symbol.circle,
.tooltip-wrapper svg .point-fallback {
transform: translateX(0.375rem) translateY(0.375rem);
}

.tooltip-wrapper svg .point-symbol:is(.diamond, .square, .triangle-down, .triangle-up) {
transform: translateX(2px) translateY(2px);
}

/* ------------------------ */
/* ----- Small charts ----- */
/* ------------------------ */
2 changes: 1 addition & 1 deletion templates/techreport/components/timeseries.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% set category = selected_subcategory or subcategory.default %}
{% set endpoint = timeseries.endpoint %}

<div data-id="{{ timeseries.id }}" data-component="timeseries" data-endpoint="{{timeseries.endpoint}}" data-category="{{category}}" data-metric="{{timeseries.metric}}" data-client="{{ request.args.get('client', '') or 'mobile' }}">
<div data-id="{{ timeseries.id }}" data-component="timeseries" data-endpoint="{{timeseries.endpoint}}" data-category="{{category}}" data-metric="{{timeseries.metric}}" data-summary="{{timeseries.viz.metric_summary}}" data-client="{{ request.args.get('client', '') or 'mobile' }}">
<div class="component-heading-wrapper">
<div class="component-heading">
{% set title = timeseries.title %}
2 changes: 0 additions & 2 deletions templates/techreport/landing.html
Original file line number Diff line number Diff line change
@@ -23,12 +23,10 @@ <h1>
<div class="card">
<h2><a href="/reports/techreport/drilldown">Technology Drilldown</a></h2>
<p>Get detailed information about <strong>one</strong> technology. </p>
<span class="img-placeholder"></span>
</div>
<div class="card">
<h2><a href="/reports/techreport/comparison">Technology Comparison</a></h2>
<p>Get detailed information about <strong>two to ten</strong> technologies. </p>
<span class="img-placeholder"></span>
</div>
</div>
</div>
4 changes: 2 additions & 2 deletions templates/techreport/techreport.html
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@
{% block report_navigation %}
<div class="info-panel">
<div class="block-l">
<p class="info-label">Beta</p>
<p class="info-label">Beta version</p>
<p>This dashboard is still under development.</p>
</div>
</div>
@@ -65,7 +65,7 @@
<h2>Feedback?</h2>
<p>
We are still working on this dashboard. The design and functionality can still change, and we're working on accessibility improvements and bugfixes.
What you're seeing here is a snapshot of our latest GitHub commit, and are <a href="https://github.com/HTTPArchive/cwv-tech-report/discussions/30">open for feedback</a>.
What you're seeing here is a snapshot of our latest GitHub commit, and are <a href="https://github.com/HTTPArchive/httparchive.org/issues">open for feedback</a>.
</p>
</div>
</div>

0 comments on commit d337ba9

Please sign in to comment.