beginning of forcecuve_compare
This commit is contained in:
@@ -522,8 +522,6 @@ def interactive_activitychart2(workouts, startdate, enddate, stack='type',
|
|||||||
return script, div
|
return script, div
|
||||||
|
|
||||||
def interactive_forcecurve(theworkouts):
|
def interactive_forcecurve(theworkouts):
|
||||||
TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair'
|
|
||||||
|
|
||||||
ids = [int(w.id) for w in theworkouts]
|
ids = [int(w.id) for w in theworkouts]
|
||||||
|
|
||||||
boattype = theworkouts[0].boattype
|
boattype = theworkouts[0].boattype
|
||||||
@@ -1990,52 +1988,42 @@ def interactive_streamchart(id=0, promember=0):
|
|||||||
def forcecurve_multi_interactive_chart(selected): # pragma: no cover
|
def forcecurve_multi_interactive_chart(selected): # pragma: no cover
|
||||||
df_plot = pd.DataFrame()
|
df_plot = pd.DataFrame()
|
||||||
ids = [analysis.id for analysis in selected]
|
ids = [analysis.id for analysis in selected]
|
||||||
|
workoutids = [analysis.workout.id for analysis in selected]
|
||||||
|
|
||||||
|
selected_dict = [ForceCurveAnalysisSerializer(analysis).data for analysis in selected]
|
||||||
|
|
||||||
columns = ['catch', 'slip', 'wash', 'finish', 'averageforce',
|
columns = ['catch', 'slip', 'wash', 'finish', 'averageforce',
|
||||||
'peakforceangle', 'peakforce', 'spm', 'distance',
|
'peakforceangle', 'peakforce', 'spm', 'distance',
|
||||||
'workoutstate', 'driveenergy']
|
'workoutstate', 'driveenergy', 'cumdist']
|
||||||
|
|
||||||
|
rowdata = dataprep.getsmallrowdata_db(columns, ids=workoutids,
|
||||||
|
workstrokesonly=False)
|
||||||
|
|
||||||
|
|
||||||
|
rowdata.dropna(axis=1, how='all', inplace=True)
|
||||||
|
rowdata.dropna(axis=0, how='any', inplace=True)
|
||||||
|
|
||||||
|
if rowdata.empty:
|
||||||
|
return "", "No Valid Data Available", "", ""
|
||||||
|
|
||||||
|
data_dict = rowdata.to_dict("records")
|
||||||
|
|
||||||
|
thresholdforces = []
|
||||||
for analysis in selected:
|
for analysis in selected:
|
||||||
workstrokesonly = not analysis.include_rest_strokes
|
boattype = analysis.workout.boattype
|
||||||
spm_min = analysis.spm_min
|
thresholdforce = 100. if 'x' in boattype else 200.
|
||||||
spm_max = analysis.spm_max
|
thresholdforces.append({'id': analysis.workout.id, 'thresholdforce': thresholdforce})
|
||||||
dist_min = analysis.dist_min
|
|
||||||
dist_max = analysis.dist_max
|
|
||||||
work_min = analysis.work_min
|
|
||||||
work_max = analysis.work_max
|
|
||||||
rowdata = dataprep.getsmallrowdata_db(columns, ids=[analysis.workout.id],
|
|
||||||
workstrokesonly=workstrokesonly)
|
|
||||||
|
|
||||||
rowdata = rowdata[rowdata['spm']>spm_min]
|
chart_data = {
|
||||||
rowdata = rowdata[rowdata['spm']<spm_max]
|
'title': '',
|
||||||
rowdata = rowdata[rowdata['driveenergy']>work_min]
|
'data': data_dict,
|
||||||
rowdata = rowdata[rowdata['driveenergy']<work_max]
|
'thresholdforces': thresholdforces,
|
||||||
rowdata = rowdata[rowdata['distance']<dist_max]
|
'forcecurve_analyses': selected_dict,
|
||||||
rowdata = rowdata[rowdata['distance']>dist_min]
|
}
|
||||||
|
|
||||||
catchav = rowdata['catch'].median()
|
|
||||||
finishav = rowdata['finish'].median()
|
|
||||||
washav = (rowdata['finish']-rowdata['wash']).median()
|
|
||||||
slipav = (rowdata['slip']+rowdata['catch']).median()
|
|
||||||
peakforceav = rowdata['peakforce'].median()
|
|
||||||
peakforceangleav = rowdata['peakforceangle'].median()
|
|
||||||
thresholdforce = 100 if 'x' in analysis.workout.boattype else 200
|
|
||||||
x = [catchav,
|
|
||||||
slipav,
|
|
||||||
peakforceangleav,
|
|
||||||
washav,
|
|
||||||
finishav]
|
|
||||||
|
|
||||||
y = [0, thresholdforce,
|
|
||||||
peakforceav,
|
|
||||||
thresholdforce, 0]
|
|
||||||
|
|
||||||
xname = 'x_'+str(analysis.id)
|
|
||||||
yname = 'y_'+str(analysis.id)
|
|
||||||
|
|
||||||
df_plot[xname] = x
|
|
||||||
df_plot[yname] = y
|
|
||||||
|
|
||||||
|
script, div = get_chart("/forcecurve_compare", chart_data)
|
||||||
|
return script, div
|
||||||
|
|
||||||
source = ColumnDataSource(
|
source = ColumnDataSource(
|
||||||
df_plot
|
df_plot
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from rest_framework import serializers
|
|||||||
from rowers.models import (
|
from rowers.models import (
|
||||||
Workout, Rower, FavoriteChart, VirtualRaceResult,
|
Workout, Rower, FavoriteChart, VirtualRaceResult,
|
||||||
VirtualRace, GeoCourse, StandardCollection, CourseStandard,
|
VirtualRace, GeoCourse, StandardCollection, CourseStandard,
|
||||||
GeoPolygon, GeoPoint, PlannedSession,
|
GeoPolygon, GeoPoint, PlannedSession, ForceCurveAnalysis
|
||||||
)
|
)
|
||||||
|
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
@@ -297,7 +297,23 @@ class GeoPointSerializer(serializers.ModelSerializer):
|
|||||||
)
|
)
|
||||||
extra_kwargs = {'id': {'read_only': False, 'required': True}}
|
extra_kwargs = {'id': {'read_only': False, 'required': True}}
|
||||||
|
|
||||||
|
class ForceCurveAnalysisSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = ForceCurveAnalysis
|
||||||
|
fields = (
|
||||||
|
'id',
|
||||||
|
'name',
|
||||||
|
'workout',
|
||||||
|
'dist_min',
|
||||||
|
'dist_max',
|
||||||
|
'spm_min',
|
||||||
|
'spm_max',
|
||||||
|
'work_min',
|
||||||
|
'work_max',
|
||||||
|
'include_rest_strokes'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class GeoPolygonSerializer(serializers.ModelSerializer):
|
class GeoPolygonSerializer(serializers.ModelSerializer):
|
||||||
points = GeoPointSerializer(many=True)
|
points = GeoPointSerializer(many=True)
|
||||||
|
|
||||||
|
|||||||
@@ -6,16 +6,9 @@
|
|||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
|
||||||
{{ js_res | safe }}
|
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
|
||||||
{{ css_res| safe }}
|
<script src="https://d3js.org/d3.v6.js"></script>
|
||||||
|
|
||||||
<script src="https://cdn.pydata.org/bokeh/release/bokeh-3.1.1.min.js"></script>
|
|
||||||
<script src="https://cdn.pydata.org/bokeh/release/bokeh-widgets-3.1.1.min.js"></script>
|
|
||||||
<script async="true" type="text/javascript">
|
|
||||||
Bokeh.set_log_level("info");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{{ the_script |safe }}
|
|
||||||
|
|
||||||
<h1>Force Curve Analysis for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
|
<h1>Force Curve Analysis for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
|
||||||
|
|
||||||
@@ -25,6 +18,7 @@
|
|||||||
<li class="grid_4">
|
<li class="grid_4">
|
||||||
<div id="theplot" class="flexplot">
|
<div id="theplot" class="flexplot">
|
||||||
{{ the_div|safe }}
|
{{ the_div|safe }}
|
||||||
|
{{ the_script |safe }}
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
Reference in New Issue
Block a user