geo-activity-playground 0.40.1__py3-none-any.whl → 0.41.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- geo_activity_playground/alembic/versions/38882503dc7c_add_tags_to_activities.py +70 -0
- geo_activity_playground/alembic/versions/script.py.mako +0 -6
- geo_activity_playground/core/activities.py +17 -30
- geo_activity_playground/core/datamodel.py +81 -0
- geo_activity_playground/webui/app.py +6 -2
- geo_activity_playground/webui/blueprints/activity_blueprint.py +20 -3
- geo_activity_playground/webui/blueprints/bubble_chart_blueprint.py +50 -25
- geo_activity_playground/webui/blueprints/calendar_blueprint.py +12 -4
- geo_activity_playground/webui/blueprints/eddington_blueprints.py +253 -0
- geo_activity_playground/webui/blueprints/entry_views.py +30 -15
- geo_activity_playground/webui/blueprints/explorer_blueprint.py +83 -9
- geo_activity_playground/webui/blueprints/summary_blueprint.py +102 -42
- geo_activity_playground/webui/columns.py +37 -0
- geo_activity_playground/webui/templates/activity/show.html.j2 +15 -4
- geo_activity_playground/webui/templates/bubble_chart/index.html.j2 +24 -8
- geo_activity_playground/webui/templates/eddington/elevation_gain.html.j2 +150 -0
- geo_activity_playground/webui/templates/elevation_eddington/index.html.j2 +150 -0
- geo_activity_playground/webui/templates/explorer/server-side.html.j2 +72 -0
- geo_activity_playground/webui/templates/home.html.j2 +14 -5
- geo_activity_playground/webui/templates/page.html.j2 +10 -1
- geo_activity_playground/webui/templates/summary/index.html.j2 +91 -2
- {geo_activity_playground-0.40.1.dist-info → geo_activity_playground-0.41.0.dist-info}/METADATA +1 -1
- {geo_activity_playground-0.40.1.dist-info → geo_activity_playground-0.41.0.dist-info}/RECORD +27 -22
- geo_activity_playground/webui/blueprints/eddington_blueprint.py +0 -194
- /geo_activity_playground/webui/templates/eddington/{index.html.j2 → distance.html.j2} +0 -0
- {geo_activity_playground-0.40.1.dist-info → geo_activity_playground-0.41.0.dist-info}/LICENSE +0 -0
- {geo_activity_playground-0.40.1.dist-info → geo_activity_playground-0.41.0.dist-info}/WHEEL +0 -0
- {geo_activity_playground-0.40.1.dist-info → geo_activity_playground-0.41.0.dist-info}/entry_points.txt +0 -0
@@ -15,6 +15,9 @@ from ...core.datamodel import DB
|
|
15
15
|
from ...core.datamodel import PlotSpec
|
16
16
|
from ...core.meta_search import apply_search_query
|
17
17
|
from ...core.parametric_plot import make_parametric_plot
|
18
|
+
from ..columns import column_distance
|
19
|
+
from ..columns import column_elevation_gain
|
20
|
+
from ..columns import ColumnDescription
|
18
21
|
from ..plot_util import make_kind_scale
|
19
22
|
from ..search_util import search_query_from_form
|
20
23
|
from ..search_util import SearchQueryHistory
|
@@ -36,25 +39,38 @@ def make_summary_blueprint(
|
|
36
39
|
kind_scale = make_kind_scale(repository.meta, config)
|
37
40
|
df = activities
|
38
41
|
|
39
|
-
year_kind_total = (
|
40
|
-
df[["year", "kind", "distance_km", "hours"]]
|
41
|
-
.groupby(["year", "kind"])
|
42
|
-
.sum()
|
43
|
-
.reset_index()
|
44
|
-
)
|
45
|
-
|
46
42
|
nominations = nominate_activities(df)
|
47
43
|
|
48
44
|
return render_template(
|
49
45
|
"summary/index.html.j2",
|
50
|
-
plot_distance_heatmaps=
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
46
|
+
plot_distance_heatmaps=plot_heatmaps(df, column_distance, config),
|
47
|
+
plot_elevation_gain_heatmaps=plot_heatmaps(
|
48
|
+
df, column_elevation_gain, config
|
49
|
+
),
|
50
|
+
plot_monthly_distance=plot_monthly_sums(df, column_distance, kind_scale),
|
51
|
+
plot_monthly_elevation_gain=plot_monthly_sums(
|
52
|
+
df, column_elevation_gain, kind_scale
|
53
|
+
),
|
54
|
+
plot_yearly_distance=plot_yearly_sums(df, column_distance, kind_scale),
|
55
|
+
plot_yearly_elevation_gain=plot_yearly_sums(
|
56
|
+
df, column_elevation_gain, kind_scale
|
57
|
+
),
|
58
|
+
plot_year_cumulative=plot_year_cumulative(df, column_distance),
|
59
|
+
plot_year_elevation_gain_cumulative=plot_year_cumulative(
|
60
|
+
df, column_elevation_gain
|
61
|
+
),
|
62
|
+
tabulate_year_kind_mean=tabulate_year_kind_mean(df, column_distance)
|
55
63
|
.reset_index()
|
56
64
|
.to_dict(orient="split"),
|
57
|
-
|
65
|
+
tabulate_year_kind_mean_elevation_gain=tabulate_year_kind_mean(
|
66
|
+
df, column_elevation_gain
|
67
|
+
)
|
68
|
+
.reset_index()
|
69
|
+
.to_dict(orient="split"),
|
70
|
+
plot_weekly_distance=plot_weekly_sums(df, column_distance, kind_scale),
|
71
|
+
plot_weekly_elevation_gain=plot_weekly_sums(
|
72
|
+
df, column_elevation_gain, kind_scale
|
73
|
+
),
|
58
74
|
nominations=[
|
59
75
|
(
|
60
76
|
repository.get_activity_by_id(activity_id),
|
@@ -109,11 +125,13 @@ def _nominate_activities_inner(
|
|
109
125
|
nominations[i].append(f"{title}{title_suffix}: {format_applied}")
|
110
126
|
|
111
127
|
|
112
|
-
def
|
128
|
+
def plot_heatmaps(
|
129
|
+
meta: pd.DataFrame, column: ColumnDescription, config: Config
|
130
|
+
) -> dict[int, str]:
|
113
131
|
return {
|
114
132
|
year: alt.Chart(
|
115
133
|
meta.loc[(meta["year"] == year)],
|
116
|
-
title="Daily
|
134
|
+
title=f"Daily {column.display_name} Heatmap",
|
117
135
|
)
|
118
136
|
.mark_rect()
|
119
137
|
.encode(
|
@@ -124,15 +142,17 @@ def plot_distance_heatmaps(meta: pd.DataFrame, config: Config) -> dict[int, str]
|
|
124
142
|
title="Year and month",
|
125
143
|
),
|
126
144
|
alt.Color(
|
127
|
-
"sum(
|
145
|
+
f"sum({column.name})",
|
128
146
|
scale=alt.Scale(scheme=config.color_scheme_for_counts),
|
129
147
|
),
|
130
148
|
[
|
131
149
|
alt.Tooltip("yearmonthdate(start)", title="Date"),
|
132
150
|
alt.Tooltip(
|
133
|
-
"sum(
|
151
|
+
f"sum({column.name})",
|
152
|
+
format=column.format,
|
153
|
+
title=f"Total {column.display_name} / {column.unit}",
|
134
154
|
),
|
135
|
-
alt.Tooltip("count(
|
155
|
+
alt.Tooltip(f"count({column.name})", title="Number of activities"),
|
136
156
|
],
|
137
157
|
)
|
138
158
|
.to_json(format="vega")
|
@@ -140,7 +160,9 @@ def plot_distance_heatmaps(meta: pd.DataFrame, config: Config) -> dict[int, str]
|
|
140
160
|
}
|
141
161
|
|
142
162
|
|
143
|
-
def
|
163
|
+
def plot_monthly_sums(
|
164
|
+
meta: pd.DataFrame, column: ColumnDescription, kind_scale: alt.Scale
|
165
|
+
) -> str:
|
144
166
|
return (
|
145
167
|
alt.Chart(
|
146
168
|
meta.loc[
|
@@ -151,20 +173,26 @@ def plot_monthly_distance(meta: pd.DataFrame, kind_scale: alt.Scale) -> str:
|
|
151
173
|
)
|
152
174
|
)
|
153
175
|
],
|
154
|
-
title="Monthly
|
176
|
+
title=f"Monthly {column.display_name}",
|
155
177
|
)
|
156
178
|
.mark_bar()
|
157
179
|
.encode(
|
158
180
|
alt.X("month(start)", title="Month"),
|
159
|
-
alt.Y(
|
181
|
+
alt.Y(
|
182
|
+
f"sum({column.name})",
|
183
|
+
title=f"{column.display_name} / {column.unit}",
|
184
|
+
),
|
160
185
|
alt.Color("kind", scale=kind_scale, title="Kind"),
|
161
186
|
alt.Column("year(start):O", title="Year"),
|
162
187
|
[
|
163
|
-
alt.Tooltip("
|
188
|
+
alt.Tooltip("yearmonth(start)", title="Year and Month"),
|
189
|
+
alt.Tooltip("kind", title="Kind"),
|
164
190
|
alt.Tooltip(
|
165
|
-
"sum(
|
191
|
+
f"sum({column.name})",
|
192
|
+
format=column.format,
|
193
|
+
title=f"Total {column.display_name} / {column.unit}",
|
166
194
|
),
|
167
|
-
alt.Tooltip("count(
|
195
|
+
alt.Tooltip(f"count({column.name})", title="Number of activities"),
|
168
196
|
],
|
169
197
|
)
|
170
198
|
.resolve_axis(x="independent")
|
@@ -172,31 +200,47 @@ def plot_monthly_distance(meta: pd.DataFrame, kind_scale: alt.Scale) -> str:
|
|
172
200
|
)
|
173
201
|
|
174
202
|
|
175
|
-
def
|
203
|
+
def plot_yearly_sums(
|
204
|
+
df: pd.DataFrame, column: ColumnDescription, kind_scale: alt.Scale
|
205
|
+
) -> str:
|
206
|
+
year_kind_total = (
|
207
|
+
df[["year", "kind", column.name, "hours"]]
|
208
|
+
.groupby(["year", "kind"])
|
209
|
+
.sum()
|
210
|
+
.reset_index()
|
211
|
+
)
|
212
|
+
|
176
213
|
return (
|
177
|
-
alt.Chart(year_kind_total, title="Total
|
214
|
+
alt.Chart(year_kind_total, title=f"Total {column.display_name} per Year")
|
178
215
|
.mark_bar()
|
179
216
|
.encode(
|
180
217
|
alt.X("year:O", title="Year"),
|
181
|
-
alt.Y(
|
218
|
+
alt.Y(column.name, title=f"{column.display_name} / {column.unit}"),
|
182
219
|
alt.Color("kind", scale=kind_scale, title="Kind"),
|
183
220
|
[
|
184
221
|
alt.Tooltip("year:O", title="Year"),
|
185
222
|
alt.Tooltip("kind", title="Kind"),
|
186
|
-
alt.Tooltip(
|
223
|
+
alt.Tooltip(
|
224
|
+
column.name,
|
225
|
+
title=f"{column.display_name} / {column.unit}",
|
226
|
+
format=column.format,
|
227
|
+
),
|
187
228
|
],
|
188
229
|
)
|
189
230
|
.to_json(format="vega")
|
190
231
|
)
|
191
232
|
|
192
233
|
|
193
|
-
def plot_year_cumulative(df: pd.DataFrame) -> str:
|
234
|
+
def plot_year_cumulative(df: pd.DataFrame, column: ColumnDescription) -> str:
|
194
235
|
year_cumulative = (
|
195
|
-
df[["iso_year", "week",
|
236
|
+
df[["iso_year", "week", column.name]]
|
196
237
|
.groupby("iso_year")
|
197
238
|
.apply(
|
198
239
|
lambda group: pd.DataFrame(
|
199
|
-
{
|
240
|
+
{
|
241
|
+
"week": group["week"],
|
242
|
+
column.name: group[column.name].cumsum(),
|
243
|
+
}
|
200
244
|
),
|
201
245
|
include_groups=False,
|
202
246
|
)
|
@@ -204,16 +248,24 @@ def plot_year_cumulative(df: pd.DataFrame) -> str:
|
|
204
248
|
)
|
205
249
|
|
206
250
|
return (
|
207
|
-
alt.Chart(
|
251
|
+
alt.Chart(
|
252
|
+
year_cumulative,
|
253
|
+
width=500,
|
254
|
+
title=f"Cumulative {column.display_name} per Year",
|
255
|
+
)
|
208
256
|
.mark_line()
|
209
257
|
.encode(
|
210
258
|
alt.X("week", title="Week"),
|
211
|
-
alt.Y(
|
259
|
+
alt.Y(column.name, title=f"{column.display_name} / {column.unit}"),
|
212
260
|
alt.Color("iso_year:N", title="Year"),
|
213
261
|
[
|
214
262
|
alt.Tooltip("week", title="Week"),
|
215
263
|
alt.Tooltip("iso_year:N", title="Year"),
|
216
|
-
alt.Tooltip(
|
264
|
+
alt.Tooltip(
|
265
|
+
column.name,
|
266
|
+
title=f"{column.display_name} / {column.unit}",
|
267
|
+
format=column.format,
|
268
|
+
),
|
217
269
|
],
|
218
270
|
)
|
219
271
|
.interactive()
|
@@ -221,24 +273,28 @@ def plot_year_cumulative(df: pd.DataFrame) -> str:
|
|
221
273
|
)
|
222
274
|
|
223
275
|
|
224
|
-
def tabulate_year_kind_mean(
|
276
|
+
def tabulate_year_kind_mean(
|
277
|
+
df: pd.DataFrame, column: ColumnDescription
|
278
|
+
) -> pd.DataFrame:
|
225
279
|
year_kind_mean = (
|
226
|
-
df[["year", "kind",
|
280
|
+
df[["year", "kind", column.name, "hours"]]
|
227
281
|
.groupby(["year", "kind"])
|
228
282
|
.mean()
|
229
283
|
.reset_index()
|
230
284
|
)
|
231
285
|
|
232
286
|
year_kind_mean_distance = year_kind_mean.pivot(
|
233
|
-
index="year", columns="kind", values=
|
287
|
+
index="year", columns="kind", values=column.name
|
234
288
|
)
|
235
289
|
|
236
290
|
return year_kind_mean_distance
|
237
291
|
|
238
292
|
|
239
|
-
def
|
293
|
+
def plot_weekly_sums(
|
294
|
+
df: pd.DataFrame, column: ColumnDescription, kind_scale: alt.Scale
|
295
|
+
) -> str:
|
240
296
|
week_kind_total_distance = (
|
241
|
-
df[["iso_year", "week", "kind",
|
297
|
+
df[["iso_year", "week", "kind", column.name]]
|
242
298
|
.groupby(["iso_year", "week", "kind"])
|
243
299
|
.sum()
|
244
300
|
.reset_index()
|
@@ -260,17 +316,21 @@ def plot_weekly_distance(df: pd.DataFrame, kind_scale: alt.Scale) -> str:
|
|
260
316
|
| (week_kind_total_distance["iso_year"] == last_year - 1)
|
261
317
|
& (week_kind_total_distance["week"] >= last_week)
|
262
318
|
],
|
263
|
-
title="Weekly
|
319
|
+
title=f"Weekly {column.display_name}",
|
264
320
|
)
|
265
321
|
.mark_bar()
|
266
322
|
.encode(
|
267
323
|
alt.X("year_week", title="Year and Week"),
|
268
|
-
alt.Y(
|
324
|
+
alt.Y(column.name, title=f"{column.display_name} / {column.unit}"),
|
269
325
|
alt.Color("kind", scale=kind_scale, title="Kind"),
|
270
326
|
[
|
271
327
|
alt.Tooltip("year_week", title="Year and Week"),
|
272
328
|
alt.Tooltip("kind", title="Kind"),
|
273
|
-
alt.Tooltip(
|
329
|
+
alt.Tooltip(
|
330
|
+
column.name,
|
331
|
+
title=f"{column.display_name} / {column.unit}",
|
332
|
+
format=column.format,
|
333
|
+
),
|
274
334
|
],
|
275
335
|
)
|
276
336
|
.to_json(format="vega")
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import dataclasses
|
2
|
+
|
3
|
+
|
4
|
+
@dataclasses.dataclass
|
5
|
+
class ColumnDescription:
|
6
|
+
name: str
|
7
|
+
display_name: str
|
8
|
+
unit: str
|
9
|
+
format: str
|
10
|
+
|
11
|
+
|
12
|
+
column_distance = ColumnDescription(
|
13
|
+
name="distance_km",
|
14
|
+
display_name="Distance",
|
15
|
+
unit="km",
|
16
|
+
format=".1f",
|
17
|
+
)
|
18
|
+
|
19
|
+
column_elevation = ColumnDescription(
|
20
|
+
name="elevation",
|
21
|
+
display_name="Elevation",
|
22
|
+
unit="m",
|
23
|
+
format=".0f",
|
24
|
+
)
|
25
|
+
column_elevation_gain = ColumnDescription(
|
26
|
+
name="elevation_gain",
|
27
|
+
display_name="Elevation Gain",
|
28
|
+
unit="m",
|
29
|
+
format=".0f",
|
30
|
+
)
|
31
|
+
|
32
|
+
column_speed = ColumnDescription(
|
33
|
+
name="speed",
|
34
|
+
display_name="Speed",
|
35
|
+
unit="km/h",
|
36
|
+
format=".1f",
|
37
|
+
)
|
@@ -49,7 +49,7 @@
|
|
49
49
|
|
50
50
|
{% if activity.elevation_gain %}
|
51
51
|
<dt>Elevation gain</dt>
|
52
|
-
<dd>{{ activity.elevation_gain|round(0) }} m</dd>
|
52
|
+
<dd>{{ activity.elevation_gain|round(0)|int }} m</dd>
|
53
53
|
{% endif %}
|
54
54
|
|
55
55
|
{% if activity.equipment %}
|
@@ -105,10 +105,21 @@
|
|
105
105
|
</style>
|
106
106
|
|
107
107
|
<div>
|
108
|
-
{% for
|
109
|
-
<span class="colorbar" style="width: 15px; background-color: {{ color }}">{{
|
108
|
+
{% for value, color in line_color_bar.colors %}
|
109
|
+
<span class="colorbar" style="width: 15px; background-color: {{ color }}">{{ value }}</span>
|
110
110
|
{% endfor %}
|
111
|
-
|
111
|
+
{{ line_color_columns_avail[line_color_column].unit }}
|
112
|
+
</div>
|
113
|
+
|
114
|
+
<div class="mb-3" style="padding-top: 10px;">
|
115
|
+
<form method="GET">
|
116
|
+
<label class="form-label">Line Color by</label>
|
117
|
+
<select class="form-select" aria-label="Line Color by" name="line_color_column" onchange="this.form.submit()">
|
118
|
+
{% for name, column in line_color_columns_avail.items() %}
|
119
|
+
<option {% if name == line_color_column %} selected {% endif %} value="{{ name }}">{{ column.display_name }}</option>
|
120
|
+
{% endfor %}
|
121
|
+
</select>
|
122
|
+
</form>
|
112
123
|
</div>
|
113
124
|
</div>
|
114
125
|
</div>
|
@@ -1,17 +1,33 @@
|
|
1
|
-
<!-- filepath: /home/michael/Nextcloud/Python/Geoactivity-Fork/geo-activity-playground/geo_activity_playground/webui/templates/bubble_chart/index.html.j2 -->
|
2
1
|
{% extends "page.html.j2" %}
|
3
2
|
|
4
3
|
{% block container %}
|
4
|
+
|
5
|
+
<div class="row mb-3">
|
6
|
+
<div class="col">
|
7
|
+
<h1>Bubble Chart: Distance</h1>
|
8
|
+
<div id="bubble-chart-distance"></div>
|
9
|
+
<script>
|
10
|
+
const chartSpecDistance = {{ bubble_chart_distance | safe }};
|
11
|
+
vegaEmbed('#bubble-chart-distance', chartSpecDistance).then((result) => {
|
12
|
+
// Add a click event listener to the chart
|
13
|
+
result.view.addEventListener('click', (event, item) => {
|
14
|
+
if (item && item.datum && item.datum.activity_url) {
|
15
|
+
// Redirect to the activity URL
|
16
|
+
window.location.href = item.datum.activity_url;
|
17
|
+
}
|
18
|
+
});
|
19
|
+
}).catch(console.error);
|
20
|
+
</script>
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
|
5
24
|
<div class="row mb-3">
|
6
25
|
<div class="col">
|
7
|
-
<h1>Bubble Chart</h1>
|
8
|
-
<div id="bubble-chart"></div>
|
9
|
-
<script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
|
10
|
-
<script src="https://cdn.jsdelivr.net/npm/vega-lite@5"></script>
|
11
|
-
<script src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
|
26
|
+
<h1>Bubble Chart: Elevation Gain</h1>
|
27
|
+
<div id="bubble-chart-elevation-gain"></div>
|
12
28
|
<script>
|
13
|
-
const
|
14
|
-
vegaEmbed('#bubble-chart',
|
29
|
+
const chartSpecElevationGain = {{ bubble_chart_elevation_gain | safe }};
|
30
|
+
vegaEmbed('#bubble-chart-elevation-gain', chartSpecElevationGain).then((result) => {
|
15
31
|
// Add a click event listener to the chart
|
16
32
|
result.view.addEventListener('click', (event, item) => {
|
17
33
|
if (item && item.datum && item.datum.activity_url) {
|
@@ -0,0 +1,150 @@
|
|
1
|
+
{% extends "page.html.j2" %}
|
2
|
+
{% from "search_form.html.j2" import search_form %}
|
3
|
+
|
4
|
+
{% block container %}
|
5
|
+
<h1 class="mb-3">Eddington Number for Elevation Gain</h1>
|
6
|
+
|
7
|
+
<div class="mb-3">
|
8
|
+
{{ search_form(query, equipments_avail, kinds_avail, search_query_favorites, search_query_last, request_url) }}
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<div class="row mb-3">
|
12
|
+
<div class="col-md-4">
|
13
|
+
<form method="GET">
|
14
|
+
<div class="mb-3">
|
15
|
+
<label class="form-label">Divisor</label>
|
16
|
+
<select class="form-select" aria-label="Divisor" name="eddington_divisor" onchange="this.form.submit()">
|
17
|
+
{% for dv in divisor_values_avail %}
|
18
|
+
<option {% if dv==eddington_divisor %} selected {% endif %}>{{ dv }}</option>
|
19
|
+
{% endfor %}
|
20
|
+
{% for key, value in query.items() %}
|
21
|
+
{% if value and key != "active" %}
|
22
|
+
{% if value is string %}
|
23
|
+
<input type="hidden" name="{{ key }}" value="{{ value }}"/>
|
24
|
+
{% else %}
|
25
|
+
{% for v in value %}
|
26
|
+
<input type="hidden" name="{{ key }}" value="{{ v }}"/>
|
27
|
+
{% endfor %}
|
28
|
+
{% endif %}
|
29
|
+
{% endif %}
|
30
|
+
{% endfor %}
|
31
|
+
</select>
|
32
|
+
</div>
|
33
|
+
</form>
|
34
|
+
|
35
|
+
<h2>Definition</h2>
|
36
|
+
|
37
|
+
<p>Your Eddington number with divisor {{ eddington_divisor }} is <b>{{ eddington_number }}</b>.</p>
|
38
|
+
|
39
|
+
<p>That means that on {{ (eddington_number / eddington_divisor) | int }} separate days you
|
40
|
+
have recorded activities with an elevation gain of more than {{ eddington_number }} m. Going high is one thing, going often is
|
41
|
+
another. But going high often is hard. Also if you increment the Eddington number, all days with less
|
42
|
+
elevation gain will not count any more. It becomes increasingly hard to increment the Eddington number because you
|
43
|
+
don't only need to achieve a higher count, but all flatter activities don't count towards the bigger number.
|
44
|
+
</p>
|
45
|
+
</div>
|
46
|
+
|
47
|
+
<div class="col-md-8">
|
48
|
+
<h2>Missing days</h2>
|
49
|
+
|
50
|
+
<p>How many more days do you need to increment your Eddington number?</p>
|
51
|
+
|
52
|
+
<table class="table">
|
53
|
+
<thead>
|
54
|
+
<tr>
|
55
|
+
<th>Elevation Gain</th>
|
56
|
+
<th>Count</th>
|
57
|
+
<th>Missing days</th>
|
58
|
+
</tr>
|
59
|
+
</thead>
|
60
|
+
<tbody>
|
61
|
+
{% for row in eddington_table %}
|
62
|
+
<tr>
|
63
|
+
<td>{{ row['elevation_gain'] }}</td>
|
64
|
+
<td>{{ row['total'] }}</td>
|
65
|
+
<td>{{ row['missing'] }}</td>
|
66
|
+
</tr>
|
67
|
+
{% endfor %}
|
68
|
+
</tbody>
|
69
|
+
</table>
|
70
|
+
</div>
|
71
|
+
</div>
|
72
|
+
|
73
|
+
<div class="row mb-1">
|
74
|
+
<div class="col">
|
75
|
+
<h2>Plot</h2>
|
76
|
+
|
77
|
+
<p>In a graphical representation, the Eddington number is the elevation gain where the red line intersects with the
|
78
|
+
blue area.</p>
|
79
|
+
|
80
|
+
{{ vega_direct("logarithmic_plot", logarithmic_plot) }}
|
81
|
+
</div>
|
82
|
+
</div>
|
83
|
+
|
84
|
+
<div class="mb-3">
|
85
|
+
<h2 class="mb-3">Eddington number history</h2>
|
86
|
+
|
87
|
+
<p>How did the Eddington number evolve over time?</p>
|
88
|
+
|
89
|
+
{{ vega_direct("eddington_number_history_plot", eddington_number_history_plot) }}
|
90
|
+
</div>
|
91
|
+
|
92
|
+
<div class="mb-3">
|
93
|
+
<h2 class="mb-3">Yearly Eddington number</h2>
|
94
|
+
|
95
|
+
<p>If we only consider the activities within one calendar year for the Eddington number, we get the following:</p>
|
96
|
+
|
97
|
+
<table class="table">
|
98
|
+
<thead>
|
99
|
+
<tr>
|
100
|
+
<th>Year</th>
|
101
|
+
<th>Eddington number</th>
|
102
|
+
</tr>
|
103
|
+
</thead>
|
104
|
+
<tbody>
|
105
|
+
{% for year, eddington in yearly_eddington.items() %}
|
106
|
+
<tr>
|
107
|
+
<td>{{ year }}</td>
|
108
|
+
<td>{{ eddington }}</td>
|
109
|
+
</tr>
|
110
|
+
{% endfor %}
|
111
|
+
</tbody>
|
112
|
+
</table>
|
113
|
+
</div>
|
114
|
+
|
115
|
+
|
116
|
+
<h2 class="mb-3">Eddington number per Week</h2>
|
117
|
+
|
118
|
+
<div class="row mb-3">
|
119
|
+
<div class="col-md-8">
|
120
|
+
{{ vega_direct("eddington_per_week_plot", eddington_per_week_plot) }}
|
121
|
+
</div>
|
122
|
+
|
123
|
+
<div class="col-md-4">
|
124
|
+
<table class="table">
|
125
|
+
<thead>
|
126
|
+
<tr>
|
127
|
+
<th>Elevation Gain</th>
|
128
|
+
<th>Count</th>
|
129
|
+
<th>Missing weeks</th>
|
130
|
+
</tr>
|
131
|
+
</thead>
|
132
|
+
<tbody>
|
133
|
+
{% for row in eddington_table_weeks %}
|
134
|
+
<tr>
|
135
|
+
<td>{{ row['elevation_gain'] }}</td>
|
136
|
+
<td>{{ row['total'] }}</td>
|
137
|
+
<td>{{ row['missing'] }}</td>
|
138
|
+
</tr>
|
139
|
+
{% endfor %}
|
140
|
+
</tbody>
|
141
|
+
</table>
|
142
|
+
</div>
|
143
|
+
</div>
|
144
|
+
|
145
|
+
<div class="row mb-1">
|
146
|
+
|
147
|
+
</div>
|
148
|
+
|
149
|
+
|
150
|
+
{% endblock %}
|