beginning of forcecuve_compare
This commit is contained in:
@@ -522,8 +522,6 @@ def interactive_activitychart2(workouts, startdate, enddate, stack='type',
|
||||
return script, div
|
||||
|
||||
def interactive_forcecurve(theworkouts):
|
||||
TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair'
|
||||
|
||||
ids = [int(w.id) for w in theworkouts]
|
||||
|
||||
boattype = theworkouts[0].boattype
|
||||
@@ -1990,52 +1988,42 @@ def interactive_streamchart(id=0, promember=0):
|
||||
def forcecurve_multi_interactive_chart(selected): # pragma: no cover
|
||||
df_plot = pd.DataFrame()
|
||||
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',
|
||||
'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:
|
||||
workstrokesonly = not analysis.include_rest_strokes
|
||||
spm_min = analysis.spm_min
|
||||
spm_max = analysis.spm_max
|
||||
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)
|
||||
boattype = analysis.workout.boattype
|
||||
thresholdforce = 100. if 'x' in boattype else 200.
|
||||
thresholdforces.append({'id': analysis.workout.id, 'thresholdforce': thresholdforce})
|
||||
|
||||
rowdata = rowdata[rowdata['spm']>spm_min]
|
||||
rowdata = rowdata[rowdata['spm']<spm_max]
|
||||
rowdata = rowdata[rowdata['driveenergy']>work_min]
|
||||
rowdata = rowdata[rowdata['driveenergy']<work_max]
|
||||
rowdata = rowdata[rowdata['distance']<dist_max]
|
||||
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
|
||||
chart_data = {
|
||||
'title': '',
|
||||
'data': data_dict,
|
||||
'thresholdforces': thresholdforces,
|
||||
'forcecurve_analyses': selected_dict,
|
||||
}
|
||||
|
||||
script, div = get_chart("/forcecurve_compare", chart_data)
|
||||
return script, div
|
||||
|
||||
source = ColumnDataSource(
|
||||
df_plot
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@ from rest_framework import serializers
|
||||
from rowers.models import (
|
||||
Workout, Rower, FavoriteChart, VirtualRaceResult,
|
||||
VirtualRace, GeoCourse, StandardCollection, CourseStandard,
|
||||
GeoPolygon, GeoPoint, PlannedSession,
|
||||
GeoPolygon, GeoPoint, PlannedSession, ForceCurveAnalysis
|
||||
)
|
||||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
@@ -297,7 +297,23 @@ class GeoPointSerializer(serializers.ModelSerializer):
|
||||
)
|
||||
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):
|
||||
points = GeoPointSerializer(many=True)
|
||||
|
||||
|
||||
@@ -6,16 +6,9 @@
|
||||
|
||||
{% block main %}
|
||||
|
||||
{{ js_res | safe }}
|
||||
{{ css_res| safe }}
|
||||
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
|
||||
<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>
|
||||
|
||||
@@ -25,6 +18,7 @@
|
||||
<li class="grid_4">
|
||||
<div id="theplot" class="flexplot">
|
||||
{{ the_div|safe }}
|
||||
{{ the_script |safe }}
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
Reference in New Issue
Block a user