Skip to content

Commit

Permalink
report: score gauges, metrics display, add rich tooltips (GoogleChrom…
Browse files Browse the repository at this point in the history
  • Loading branch information
paulirish authored and kdzwinel committed Aug 16, 2018
1 parent 2573e82 commit 6eda27b
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 158 deletions.
27 changes: 10 additions & 17 deletions lighthouse-core/report/v2/renderer/category-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,26 +235,19 @@ class CategoryRenderer {
*/
renderScoreGauge(category) {
const tmpl = this.dom.cloneTemplate('#tmpl-lh-gauge', this.templateContext);
this.dom.find('.lh-gauge__wrapper', tmpl).href = `#${category.id}`;
this.dom.find('.lh-gauge__label', tmpl).textContent = category.name;

const scoreOutOf100 = Math.round(category.score * 100);
const fillRotation = Math.floor((scoreOutOf100 / 100) * 180);
const wrapper = this.dom.find('.lh-gauge__wrapper', tmpl);
wrapper.href = `#${category.id}`;
wrapper.classList.add(`lh-gauge__wrapper--${Util.calculateRating(category.score)}`);

const gauge = this.dom.find('.lh-gauge', tmpl);
gauge.setAttribute('data-progress', scoreOutOf100); // .dataset not supported in jsdom.
gauge.classList.add(`lh-gauge--${Util.calculateRating(category.score)}`);

this.dom.findAll('.lh-gauge__fill', gauge).forEach(el => {
el.style.transform = `rotate(${fillRotation}deg)`;
});

this.dom.find('.lh-gauge__mask--full', gauge).style.transform =
`rotate(${fillRotation}deg)`;
this.dom.find('.lh-gauge__fill--fix', gauge).style.transform =
`rotate(${fillRotation * 2}deg)`;
this.dom.find('.lh-gauge__percentage', gauge).textContent = scoreOutOf100;
// 329 is ~= 2 * Math.PI * gauge radius (53)
// https://codepen.io/xgad/post/svg-radial-progress-meters
// score of 50: `stroke-dasharray: 164.5 329`;
this.dom.find('.lh-gauge-arc', gauge).style.strokeDasharray = `${category.score * 329} 329`;

const scoreOutOf100 = Math.round(category.score * 100);
this.dom.find('.lh-gauge__percentage', tmpl).textContent = scoreOutOf100;
this.dom.find('.lh-gauge__label', tmpl).textContent = category.name;
return tmpl;
}

Expand Down
54 changes: 25 additions & 29 deletions lighthouse-core/report/v2/renderer/performance-category-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,20 @@
class PerformanceCategoryRenderer extends CategoryRenderer {
/**
* @param {!ReportRenderer.AuditJSON} audit
* @param {number} scale
* @return {!Element}
*/
_renderTimelineMetricAudit(audit, scale) {
const tmpl = this.dom.cloneTemplate('#tmpl-lh-timeline-metric', this.templateContext);
const element = this.dom.find('.lh-timeline-metric', tmpl);
element.classList.add(`lh-timeline-metric--${Util.calculateRating(audit.result.score)}`);
_renderMetric(audit) {
const tmpl = this.dom.cloneTemplate('#tmpl-lh-perf-metric', this.templateContext);
const element = this.dom.find('.lh-perf-metric', tmpl);
element.classList.add(`lh-perf-metric--${Util.calculateRating(audit.result.score)}`);

const titleEl = this.dom.find('.lh-timeline-metric__title', tmpl);
const titleEl = this.dom.find('.lh-perf-metric__title', tmpl);
titleEl.textContent = audit.result.description;

const valueEl = this.dom.find('.lh-timeline-metric__value', tmpl);
const valueEl = this.dom.find('.lh-perf-metric__value span', tmpl);
valueEl.textContent = audit.result.displayValue;

const descriptionEl = this.dom.find('.lh-timeline-metric__description', tmpl);
const descriptionEl = this.dom.find('.lh-perf-metric__description', tmpl);
descriptionEl.appendChild(this.dom.convertMarkdownLinkSnippets(audit.result.helpText));

if (typeof audit.result.rawValue !== 'number') {
Expand All @@ -33,9 +32,6 @@ class PerformanceCategoryRenderer extends CategoryRenderer {
return element;
}

const sparklineBarEl = this.dom.find('.lh-sparkline__bar', tmpl);
sparklineBarEl.style.width = `${audit.result.rawValue / scale * 100}%`;

return element;
}

Expand Down Expand Up @@ -119,38 +115,37 @@ class PerformanceCategoryRenderer extends CategoryRenderer {

const metricAudits = category.audits.filter(audit => audit.group === 'perf-metric');
const metricAuditsEl = this.renderAuditGroup(groups['perf-metric'], {expandable: false});
const timelineContainerEl = this.dom.createChildOf(metricAuditsEl, 'div',
'lh-timeline-container');
const timelineEl = this.dom.createChildOf(timelineContainerEl, 'div', 'lh-timeline');

let perfTimelineScale = 0;
metricAudits.forEach(audit => {
if (typeof audit.result.rawValue === 'number' && audit.result.rawValue) {
perfTimelineScale = Math.max(perfTimelineScale, audit.result.rawValue);
}

// Metrics
const keyMetrics = metricAudits.filter(a => a.weight >= 3);
const otherMetrics = metricAudits.filter(a => a.weight < 3);

const metricsBoxesEl = this.dom.createChildOf(metricAuditsEl, 'div', 'lh-metrics-container');
const metricsColumn1El = this.dom.createChildOf(metricsBoxesEl, 'div', 'lh-metrics-column');
const metricsColumn2El = this.dom.createChildOf(metricsBoxesEl, 'div', 'lh-metrics-column');

keyMetrics.forEach(item => {
metricsColumn1El.appendChild(this._renderMetric(item));
});
otherMetrics.forEach(item => {
metricsColumn2El.appendChild(this._renderMetric(item));
});

// Filmstrip
const timelineEl = this.dom.createChildOf(metricAuditsEl, 'div', 'lh-timeline');
const thumbnailAudit = category.audits.find(audit => audit.id === 'screenshot-thumbnails');
const thumbnailResult = thumbnailAudit && thumbnailAudit.result;
if (thumbnailResult && thumbnailResult.details) {
const thumbnailDetails = /** @type {!DetailsRenderer.FilmstripDetails} */
(thumbnailResult.details);
perfTimelineScale = Math.max(perfTimelineScale, thumbnailDetails.scale);
const filmstripEl = this.detailsRenderer.render(thumbnailDetails);
timelineEl.appendChild(filmstripEl);
}

metricAudits.forEach(item => {
if (item.id === 'speed-index' || item.id === 'estimated-input-latency') {
return metricAuditsEl.appendChild(this.renderAudit(item));
}

timelineEl.appendChild(this._renderTimelineMetricAudit(item, perfTimelineScale));
});

metricAuditsEl.open = true;
element.appendChild(metricAuditsEl);

// Opportunities
const hintAudits = category.audits
.filter(audit => audit.group === 'perf-hint' && audit.result.score < 1)
.sort((auditA, auditB) => auditB.result.rawValue - auditA.result.rawValue);
Expand All @@ -163,6 +158,7 @@ class PerformanceCategoryRenderer extends CategoryRenderer {
element.appendChild(hintAuditsEl);
}

// Diagnostics
const infoAudits = category.audits
.filter(audit => audit.group === 'perf-info' && audit.result.score < 1);
if (infoAudits.length) {
Expand Down
3 changes: 3 additions & 0 deletions lighthouse-core/report/v2/renderer/report-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ class ReportRenderer {
categories.appendChild(renderer.render(category, report.reportGroups));
}

const scoreScale = this._dom.cloneTemplate('#tmpl-lh-scorescale', this._templateContext);
scoreHeader.appendChild(scoreScale);

reportSection.appendChild(this._renderReportFooter(report));

return container;
Expand Down
Loading

0 comments on commit 6eda27b

Please sign in to comment.