-
Notifications
You must be signed in to change notification settings - Fork 4
/
activityTop10V2.js
204 lines (180 loc) · 5.19 KB
/
activityTop10V2.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/* eslint-disable camelcase */
/* eslint-disable require-jsdoc */
"use strict";
//
// DOM elements
//
const html_sel_type = document.getElementById("sel-type");
const html_sel_measure = document.getElementById("sel-measure");
const html_yearMin = document.getElementById("sel-yearMin");
const html_yearMax = document.getElementById("sel-yearMax");
//
// Global variables
//
let data_all = [];
let data_rank = [];
const promises = []; // array of promises for async fetching
// measures used in table and in select
const measures = {
x_min: "Duration",
x_km: "Distance",
"km/h": "Speed",
total_elevation_gain: "Elevation",
"x_elev_m/km": "Elev. m/km",
x_dist_start_end_km: "Dist Start-End",
average_heartrate: "Heartrate avg",
kilojoules: "KJ",
};
// add options to html_sel_measure
helper_populate_select(html_sel_measure, measures, null, true);
const columns = [];
columns.push(helper_tabulator_col_num("rank", "#"));
columns.push(helper_tabulator_col_str("x_date", "Date"));
columns.push(helper_tabulator_col_str("name", "Name", 300));
for (let i = 0; i < Object.keys(measures).length; i++) {
const key = Object.keys(measures)[i];
columns.push(helper_tabulator_col_num(key, measures[key]));
}
//
// Data fetching
//
const fetch_data = async (session) => {
const url = `https://entorb.net/strava/download/${session}/activityList.json`;
try {
const response = await fetch(url);
const data = await response.json();
console.log("done download activityList.json");
// delete not needed object properties
const allowedKeys = new Set([
"type",
"name",
"x_date",
"x_url",
...Object.keys(measures),
]);
data.forEach((obj) => {
Object.entries(obj).forEach(([key]) => {
if (!allowedKeys.has(key)) {
delete obj[key];
}
});
// extract year from x_date and add as property
obj.year = parseInt(obj.x_date.substr(0, 4));
});
data_all = data;
use_data_all_to_populate_html_elements();
} catch (error) {
console.log("failed download activityList.json");
}
};
// Start the async fetching
promises.push(fetch_data(session));
function use_data_all_to_populate_html_elements() {
// extract activity types and populate select
const act_types = [...new Set(data_all.map((obj) => obj.type))].sort();
// convert into object of key->value with key = value
const act_types_map = helper_array_to_object_of_key_eq_value(act_types);
helper_populate_select(html_sel_type, act_types_map, "Run", true);
// extract min and may year value
const yearMin = Math.min(...data_all.map((obj) => obj.year));
const yearMax = Math.max(...data_all.map((obj) => obj.year));
html_yearMin.value = yearMin;
html_yearMin.min = yearMin;
html_yearMin.max = yearMax;
html_yearMax.value = yearMax;
html_yearMax.min = yearMin;
html_yearMax.max = yearMax;
}
function defineTable() {
const table = new Tabulator("#table-activity-list", {
// height: "100%",
maxHeight: "100%", // do not let table get bigger than the height of its parent element
// height: 800,
layout: "fitDataStretch", // fit columns to width of table (optional)
tooltipsHeader: false,
selectable: false, // for row click
columns: columns,
});
return table;
}
const table = defineTable();
// row click event -> open Strava
table.on("cellClick", (e, cell) => {
const row = cell.getRow();
const rowData = row.getData();
const activityUrl = rowData.x_url;
window.open(activityUrl);
});
// add promise for tableBuilt event
promises.push(
new Promise((resolve) => {
table.on("tableBuilt", () => {
console.log("tableBuilt");
resolve();
});
})
);
// data_all -> data_rank
function ranking() {
const type = html_sel_type.value;
const measure = html_sel_measure.value;
// filter data on
// type
// measure not null/missing
// year
data_rank = data_all.filter(
(obj) =>
obj.type === type &&
obj[measure] !== null &&
obj[measure] !== undefined &&
obj[measure] != 0 &&
obj["year"] >= html_yearMin.value &&
obj["year"] <= html_yearMax.value
);
// sort by measure DESC
data_rank = data_rank.sort((a, b) => b[measure] - a[measure]);
// add rank column
data_rank = data_rank.map((element, index) => {
return {
...element,
rank: index + 1,
};
});
// send data to table
table.setData(data_rank);
// unhide all columns
table.getColumns().forEach(function (column) {
table.showColumn(column.getField());
});
// hide some columns
if (type === "Swim") {
table.hideColumn("total_elevation_gain");
table.hideColumn("x_elev_m/km");
}
if (type === "Ride") {
table.showColumn("kilojoules");
} else {
table.hideColumn("kilojoules");
}
}
//
// Event listeners
//
html_sel_type.addEventListener("change", () => {
ranking();
});
html_sel_measure.addEventListener("change", () => {
ranking();
});
html_yearMin.addEventListener("change", () => {
html_yearMax.min = html_yearMin.value;
ranking();
});
html_yearMax.addEventListener("change", () => {
html_yearMin.max = html_yearMax.value;
ranking();
});
// Wait for all async promises to be done (all data is fetched)
Promise.all(promises).then(function () {
ranking();
});