Skip to content

Commit f2eec8d

Browse files
committed
Prepare cwv-distribution to use live API with fallback to bundled data
Fetches from /v1/cwv-distribution (tech-report-apis#105) when the endpoint is available. Falls back to bundled sample data on fetch failure until the API is deployed.
1 parent 576ec70 commit f2eec8d

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

src/js/techreport/cwvDistribution.js

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/* global Highcharts */
22

3-
// Hardcoded distribution data — will be replaced by API fetch when the endpoint is finalized
4-
import distributionData from './cwvDistributionData.json';
3+
import { Constants } from './utils/constants';
4+
// Fallback data used until the API endpoint is deployed (see tech-report-apis#105)
5+
import fallbackData from './cwvDistributionData.json';
56

67
const METRIC_CONFIG = {
78
LCP: { bucketField: 'loading_bucket', originsField: 'lcp_origins', unit: 'ms', label: 'LCP (ms)' },
@@ -26,11 +27,12 @@ const ZONE_COLORS = {
2627
};
2728

2829
class CwvDistribution {
29-
// pageConfig, config, filters, data are accepted to satisfy the Section component contract
30+
// pageConfig, config are accepted to satisfy the Section component contract
3031
constructor(id, pageConfig, config, filters, data) {
3132
this.id = id;
3233
this.pageFilters = filters;
3334
this.data = data;
35+
this.distributionData = null;
3436
this.selectedMetric = 'LCP';
3537
this.chart = null;
3638
this.root = document.querySelector(`[data-id="${this.id}"]`);
@@ -46,16 +48,16 @@ class CwvDistribution {
4648
root.querySelectorAll('.cwv-distribution-metric-selector').forEach(dropdown => {
4749
dropdown.addEventListener('change', event => {
4850
this.selectedMetric = event.target.value;
49-
this.renderChart();
51+
if (this.distributionData) this.renderChart();
5052
});
5153
});
5254

53-
// Lazy render on <details> toggle
55+
// Lazy fetch + render on <details> toggle
5456
const details = root.closest('details');
5557
if (details) {
5658
details.addEventListener('toggle', () => {
57-
if (details.open && !this.chart) {
58-
this.renderChart();
59+
if (details.open && !this.distributionData) {
60+
this.fetchData();
5961
} else if (details.open && this.chart) {
6062
this.chart.reflow();
6163
}
@@ -64,7 +66,34 @@ class CwvDistribution {
6466
}
6567

6668
updateContent() {
67-
if (this.chart) this.renderChart();
69+
if (this.distributionData) this.renderChart();
70+
}
71+
72+
fetchData() {
73+
const technology = this.pageFilters.app.map(encodeURIComponent).join(',');
74+
const rank = encodeURIComponent(this.pageFilters.rank || 'ALL');
75+
const date = this.root?.dataset?.latestDate || '';
76+
77+
let url = `${Constants.apiBase}/cwv-distribution?technology=${technology}&rank=${rank}`;
78+
if (date) {
79+
url += `&date=${encodeURIComponent(date)}`;
80+
}
81+
82+
fetch(url)
83+
.then(r => {
84+
if (!r.ok) throw new Error(`HTTP ${r.status}`);
85+
return r.json();
86+
})
87+
.then(rows => {
88+
if (!Array.isArray(rows) || rows.length === 0) throw new Error('Empty response');
89+
this.distributionData = rows;
90+
this.renderChart();
91+
})
92+
.catch(() => {
93+
// Fall back to bundled sample data until the API is deployed
94+
this.distributionData = fallbackData;
95+
this.renderChart();
96+
});
6897
}
6998

7099
trimWithOverflow(rows, originsField, percentile) {
@@ -88,15 +117,15 @@ class CwvDistribution {
88117
}
89118

90119
renderChart() {
91-
if (!distributionData || distributionData.length === 0) return;
120+
if (!this.distributionData || this.distributionData.length === 0) return;
92121
if (!this.root) return;
93122

94123
const client = this.root.dataset.client || 'mobile';
95124
const metricCfg = METRIC_CONFIG[this.selectedMetric];
96125
const thresholds = THRESHOLDS[this.selectedMetric] || [];
97126

98127
// Filter by client and sort by bucket
99-
const clientRows = distributionData
128+
const clientRows = this.distributionData
100129
.filter(row => row.client === client)
101130
.sort((a, b) => a[metricCfg.bucketField] - b[metricCfg.bucketField]);
102131

@@ -210,7 +239,6 @@ class CwvDistribution {
210239
}],
211240
credits: { enabled: false },
212241
});
213-
214242
}
215243
}
216244

templates/techreport/components/cwv_distribution.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ <h3>{{ cwv_distribution_config.title }}</h3>
1010
data-id="{{ cwv_distribution_config.id }}"
1111
data-component="cwvDistribution"
1212
data-client="{{ request.args.get('client', '') or 'mobile' }}"
13+
data-latest-date="{{ all_dates[0].value if all_dates else '' }}"
1314
>
1415
<div class="component-heading-wrapper">
1516
<div class="component-heading">

0 commit comments

Comments
 (0)