Commit 72f60cde authored by Xavier de Blas's avatar Xavier de Blas

fixed: 504069 "Create two new RJ evo with AVG and SD stats and graph". Done stats & graphs

svn path=/trunk/; revision=344
parent cb524f0f
......@@ -34,9 +34,9 @@ CHRONOJUMP_SERVER = chronojump_server
CHRONOJUMP_DEP_GUI = src/gui/chronojump.cs src/gui/confirm.cs src/gui/error.cs src/gui/eventExecute.cs src/gui/eventGraphConfigure.cs src/gui/event.cs src/gui/jump.cs src/gui/jumpType.cs src/gui/run.cs src/gui/runType.cs src/gui/reactionTime.cs src/gui/pulse.cs src/gui/person.cs src/gui/preferences.cs src/gui/session.cs src/gui/stats.cs src/gui/report.cs src/gui/about.cs src/gui/helpPorts.cs src/gui/dialogMessage.cs src/gui/dialogHelp.cs src/gui/dialogCalendar.cs src/gui/dialogImageTest.cs src/gui/language.cs src/gui/repetitiveConditions.cs src/gui/chronopicConnection.cs src/gui/convertWeight.cs
CHRONOJUMP_DEP_STATS = src/statType.cs src/stats/main.cs src/stats/global.cs src/stats/sjCmjAbk.cs src/stats/sjCmjAbkPlus.cs src/stats/djIndex.cs src/stats/djQ.cs src/stats/rjIndex.cs src/stats/rjPotencyBosco.cs src/stats/rjEvolution.cs src/stats/ieIub.cs src/stats/fv.cs src/stats/potency.cs
CHRONOJUMP_DEP_STATS = src/statType.cs src/stats/main.cs src/stats/global.cs src/stats/sjCmjAbk.cs src/stats/sjCmjAbkPlus.cs src/stats/djIndex.cs src/stats/djQ.cs src/stats/rjIndex.cs src/stats/rjPotencyBosco.cs src/stats/rjEvolution.cs src/stats/ieIub.cs src/stats/fv.cs src/stats/potency.cs src/stats/rjAVGSD.cs
CHRONOJUMP_DEP_GRAPHS = src/stats/graphs/graphData.cs src/stats/graphs/graphSerie.cs src/stats/graphs/global.cs src/stats/graphs/sjCmjAbk.cs src/stats/graphs/sjCmjAbkPlus.cs src/stats/graphs/djIndex.cs src/stats/graphs/djQ.cs src/stats/graphs/rjIndex.cs src/stats/graphs/rjPotencyBosco.cs src/stats/graphs/rjEvolution.cs src/stats/graphs/ieIub.cs src/stats/graphs/fv.cs src/stats/graphs/potency.cs
CHRONOJUMP_DEP_GRAPHS = src/stats/graphs/graphData.cs src/stats/graphs/graphSerie.cs src/stats/graphs/global.cs src/stats/graphs/sjCmjAbk.cs src/stats/graphs/sjCmjAbkPlus.cs src/stats/graphs/djIndex.cs src/stats/graphs/djQ.cs src/stats/graphs/rjIndex.cs src/stats/graphs/rjPotencyBosco.cs src/stats/graphs/rjEvolution.cs src/stats/graphs/ieIub.cs src/stats/graphs/fv.cs src/stats/graphs/potency.cs src/stats/graphs/rjAVGSD.cs
CHRONOJUMP_DEP_SQLITE = src/sqlite/main.cs src/sqlite/preferences.cs src/sqlite/person.cs src/sqlite/session.cs src/sqlite/jump.cs src/sqlite/jumpType.cs src/sqlite/run.cs src/sqlite/runType.cs src/sqlite/personSession.cs src/sqlite/stat.cs src/sqlite/pulse.cs src/sqlite/pulseType.cs src/sqlite/reactionTime.cs src/sqlite/event.cs
......
CHRONOJUMP DETAILED CHANGELOG:
18 dec 2007
fixed: 504069 "Create two new RJ evo with AVG and SD stats and
graph". Done stats & graphs
7 dec 2007 (Major RELEASE 0.62 for Linux and windows)
avg works on all graphs simple session & multisession (obvioulsy if they have
avg and sd statistics (global and rjEvolution, not)
......
......@@ -89,9 +89,15 @@ public class Constants
"+ (40.8*(" + Catalog.GetString("body weight") + "+" + Catalog.GetString("extra weight") + ")) -1731.1";
public static string RJPotencyBoscoFormula = Catalog.GetString("Peak Power") + " (Bosco)" + "\n 9.81^2*TF*TT / (4*jumps*(TT-TF))";
public static string RJPotencyBoscoName = Catalog.GetString("Peak Power") + " (Bosco)";
public static string RjIndexName = "Rj Index";
public static string QIndexName = "Q Index";
public static string RjIndexOnlyFormula = "(tf-tc)/tc *100)";
public static string QIndexOnlyFormula = "(tf/tc)";
public static string RJAVGSDRjIndexName = Catalog.GetString("Reactive AVG SD") + " (" + RjIndexName + ")";
public static string RJAVGSDQIndexName = Catalog.GetString("Reactive AVG SD") + " (" + QIndexName + ")";
//global stat types
public static string TypeSessionSummary = Catalog.GetString("Session summary");
......
......@@ -110,7 +110,9 @@ public class StatsWindow {
private static string [] comboStatsSubTypeReactiveOptions = {
Catalog.GetString("Average Index"),
Constants.RJPotencyBoscoFormula,
Catalog.GetString("Evolution")
Catalog.GetString("Evolution"),
Constants.RJAVGSDRjIndexName,
Constants.RJAVGSDQIndexName
};
private static string [] comboStatsSubTypeSimpleOptions = {
......@@ -732,7 +734,10 @@ public class StatsWindow {
} else {
//some stats should not be showed as limited jumps
if(statisticType == Constants.TypeJumpsReactive &&
statisticSubType == Catalog.GetString("Evolution") ) {
( statisticSubType == Catalog.GetString("Evolution") ||
statisticSubType == Constants.RJAVGSDRjIndexName ||
statisticSubType == Constants.RJAVGSDQIndexName)
) {
//don't allow Evolution be multisession
radiobutton_current_session.Active = true;
radiobutton_selected_sessions.Sensitive = false;
......
......@@ -601,6 +601,8 @@ class SqliteStat : Sqlite
}
//maxJumps for make all the results of same length (fill it with '-'s)
//rjAVGSD also calls this method
//but both of them are simple session
public static ArrayList RjEvolution (string sessionString, bool multisession, string operationString, string jumpType, bool showSex, int maxJumps)
{
string ini = "";
......@@ -667,22 +669,30 @@ class SqliteStat : Sqlite
if(jumpType == Catalog.GetString("All jumps") && operationString != "AVG") {
showJumpTypeString = " (" + reader[7].ToString() + ")";
}
/*
if(multisession) {
returnSessionString = ":" + reader[2].ToString();
} else {
//in multisession we show only one column x session
//in simplesession we show all
//convert the strings of TFs and TCs separated by '=' in
//one string mixed and separated by ':'
allTCsTFsCombined = combineTCsTFs(
Util.ChangeDecimalSeparator(reader[4].ToString()),
Util.ChangeDecimalSeparator(reader[5].ToString()),
maxJumps);
returnFallString = ":" + reader[6].ToString();
}
*/
/*
* RjEvolution does not work in multisession,
* but other stats like rjAVGSD who call this rjEvolution stats method
* work for simple and multisession
*/
//convert the strings of TFs and TCs separated by '=' in
//one string mixed and separated by ':'
allTCsTFsCombined = combineTCsTFs(
Util.ChangeDecimalSeparator(reader[4].ToString()),
Util.ChangeDecimalSeparator(reader[5].ToString()),
maxJumps);
returnFallString = ":" + reader[6].ToString();
myArray.Add (reader[0].ToString() + showSexString + showJumpTypeString +
returnSessionString + ":" + //session
Util.ChangeDecimalSeparator(reader[3].ToString()) + //index
......
......@@ -360,12 +360,27 @@ public class StatType {
else if(statisticSubType == Catalog.GetString("Evolution"))
{
if(graph) {
//myStat = new GraphRjEvolution (myStatTypeStruct, rj_evolution_mark_consecutives);
myStat = new GraphRjEvolution (myStatTypeStruct, rj_evolution_mark_consecutives);
} else {
myStat = new StatRjEvolution(myStatTypeStruct, rj_evolution_mark_consecutives, treeview_stats);
}
}
else if(statisticSubType == Constants.RJAVGSDRjIndexName)
{
if(graph) {
myStat = new GraphRjAVGSD(myStatTypeStruct, Constants.RjIndexName);
} else {
myStat = new StatRjAVGSD(myStatTypeStruct, treeview_stats, Constants.RjIndexName);
}
}
else if(statisticSubType == Constants.RJAVGSDQIndexName)
{
if(graph) {
myStat = new GraphRjAVGSD(myStatTypeStruct, Constants.QIndexName);
} else {
myStat = new StatRjAVGSD(myStatTypeStruct, treeview_stats, Constants.QIndexName);
}
}
}
myStat.FakeButtonRowCheckedUnchecked.Clicked +=
......
/*
* This file is part of ChronoJump
*
* ChronoJump is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ChronoJump is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Xavier de Blas:
* http://www.xdeblas.com, http://www.deporteyciencia.com (parleblas)
*/
using System;
using System.Data;
using Gtk;
using System.Collections; //ArrayList
using NPlot.Gtk;
using NPlot;
using System.Drawing;
using System.Drawing.Imaging;
using Mono.Unix;
public class GraphRjAVGSD : StatRjAVGSD
{
protected string operation;
private Random myRand = new Random();
private int countSeriesGraphColors = 0;
//for simplesession
GraphSerie serieAVG;
GraphSerie serieSD;
public GraphRjAVGSD (StatTypeStruct myStatTypeStruct, string indexType)
{
this.indexType = indexType;
completeConstruction (myStatTypeStruct, treeview);
this.dataColumns = 2; //for Simplesession (avg, sd)
//no average for this stat
//if (statsJumpsType == 2) {
this.operation = "MAX";
/*
} else {
this.operation = "AVG";
}
*/
CurrentGraphData.WindowTitle = Catalog.GetString("ChronoJump graph");
//title is shown on the graph except it's a report, then title will be on the html
if(myStatTypeStruct.ToReport) {
CurrentGraphData.GraphTitle = "";
} else {
//CurrentGraphData.GraphTitle = this.ToString();
CurrentGraphData.GraphTitle = "";
}
serieAVG = new GraphSerie();
serieSD = new GraphSerie();
serieAVG.Title = Catalog.GetString("Average");
serieSD.Title = Catalog.GetString("SD");
serieAVG.IsLeftAxis = true;
serieSD.IsLeftAxis = true;
serieAVG.SerieMarker = new Marker (Marker.MarkerType.FilledCircle,
6, new Pen (Color.FromName("Red"), 2.0F));
serieSD.SerieMarker = new Marker (Marker.MarkerType.Cross1,
6, new Pen (Color.FromName("Black"), 2.0F));
//for the line between markers
serieAVG.SerieColor = Color.FromName("Red");
serieSD.SerieColor = Color.FromName("Black");
CurrentGraphData.LabelLeft = Catalog.GetString("seconds");
CurrentGraphData.LabelRight = "";
}
protected override void printData (string [] statValues)
{
//values are recorded for calculating later AVG and SD
recordStatValues(statValues);
//only simpleSession
int i = 0;
//we need to save this transposed
foreach (string myValue in statValues)
{
if(i == 0)
CurrentGraphData.XAxisNames.Add(myValue);
else if(i == 1)
serieAVG.SerieData.Add(myValue);
else if(i == 2)
serieSD.SerieData.Add(myValue);
if (i == 2)
i = 0;
else
i++;
}
//add created series to GraphSeries ArrayList
//check don't do it two times
if(GraphSeries.Count == 0) {
GraphSeries.Add(serieAVG);
GraphSeries.Add(serieSD);
}
}
protected override int plotGraphGraphSeries (IPlotSurface2D plot, int xtics, ArrayList allSeries)
{
double[] lineData = new double[ xtics ];
Marker m = serieAVG.SerieMarker;
Marker mSDUp = new Marker (Marker.MarkerType.TriangleUp,
6, new Pen (Color.FromName("Black"), 1.0F));
Marker mSDDown = new Marker (Marker.MarkerType.TriangleDown,
6, new Pen (Color.FromName("Black"), 1.0F));
PointPlot pp;
LinePlot lp;
PointPlot ppSDUp;
PointPlot ppSDDown;
pp = new PointPlot( m );
pp.Label = serieAVG.Title;
lp = new LinePlot();
lp.Label = serieAVG.Title;
lp.Color = serieAVG.SerieColor;
ppSDUp = new PointPlot( mSDUp );
ppSDDown = new PointPlot( mSDDown );
ppSDUp.Label = serieSD.Title;
//left margin
lineData[0] = double.NaN;
int added=1;
int counter=0;
foreach (string myValue in serieAVG.SerieData)
{
//in single session lineData should contain all rows from stats except unchecked
if(sessions.Count == 1 && ! acceptCheckedData(counter) ) {
counter ++;
continue;
}
if(myValue == "-")
lineData[added++] = double.NaN;
else
lineData[added++] = Convert.ToDouble(myValue);
counter++;
}
//right margin
lineData[added] = double.NaN;
lp.DataSource = lineData;
pp.OrdinateData = lineData;
ppSDUp.OrdinateData = convertLineDataToSDData(lineData, serieSD.SerieData, true);
ppSDDown.OrdinateData = convertLineDataToSDData(lineData, serieSD.SerieData, false);
pp.AbscissaData = new StartStep( 0, 1 ); //ini 0, step 1 (ini 0 because in lineData we start with blank value)
ppSDUp.AbscissaData = new StartStep( 0, 1 );
ppSDDown.AbscissaData = new StartStep( 0, 1 );
pp.ShowInLegend = false;
ppSDUp.ShowInLegend = true; //only need to show it one time
ppSDDown.ShowInLegend = false;
plot.Add( lp );
plot.Add( pp );
plot.Add( ppSDUp );
plot.Add( ppSDDown );
int acceptedSerie = 1;
return acceptedSerie; //for knowing if a serie was accepted, and then createAxisGraphSeries
}
private double[] convertLineDataToSDData(double[] lineData, ArrayList serieSDData, bool up) {
double[] lineDataReturn = new double[ lineData.Length ];
int i = 1;
for(i=1; i < lineData.Length -1; i ++) {
if(lineData[i] != double.NaN) {
int j = 0;
foreach(string mySD in serieSDData) {
if(j+1 == i) {
if(up)
lineDataReturn[i] = lineData[i] + Convert.ToDouble(mySD);
else
lineDataReturn[i] = lineData[i] - Convert.ToDouble(mySD);
break;
}
j++;
}
} else
lineDataReturn[i] = double.NaN;
}
lineDataReturn[i] = double.NaN;
return lineDataReturn;
}
}
......@@ -1032,7 +1032,7 @@ public class Stat
}
*/
bool acceptCheckedData(int myData) {
protected bool acceptCheckedData(int myData) {
foreach(string marked in markedRows) {
if(Convert.ToInt32(marked) == myData) {
return true;
......@@ -1054,15 +1054,15 @@ public class Stat
}
}
protected int plotGraphGraphSeries (IPlotSurface2D plot, int xtics, ArrayList allSeries)
protected virtual int plotGraphGraphSeries (IPlotSurface2D plot, int xtics, ArrayList allSeries)
{
rjEvolutionMaxJumps = -1;
int acceptedSerie = 0;
int countSerie = 0;
foreach(GraphSerie mySerie in allSeries)
{
//in isRjEvolution then check it this serie will be shown (each jumper has a TC and a TF serie)
if( isRjEvolution && ! acceptCheckedData( divideAndRoundDown(countSerie)) ) {
countSerie ++;
......
/*
* This file is part of ChronoJump
*
* ChronoJump is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ChronoJump is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Xavier de Blas:
* http://www.xdeblas.com, http://www.deporteyciencia.com (parleblas)
*/
using System;
using System.Data;
using Gtk;
using System.Collections; //ArrayList
using Mono.Unix;
public class StatRjAVGSD : Stat
{
protected string indexType;
protected string [] columnsString = {
Catalog.GetString("Jumper"),
Catalog.GetString("AVG"),
Catalog.GetString("SD") };
//if this is not present i have problems like (No overload for method `xxx' takes `0' arguments) with some inherited classes
public StatRjAVGSD ()
{
this.showSex = false;
this.statsJumpsType = 0;
this.limit = 0;
}
public StatRjAVGSD (StatTypeStruct myStatTypeStruct, Gtk.TreeView treeview, string indexType)
{
completeConstruction (myStatTypeStruct, treeview);
this.indexType = indexType;
this.dataColumns = 2; //for simplesession (index, height, tv, tc, fall)
/*
* only simplesession, because it has to plot two values: AVG, and SD
if(sessions.Count > 1) {
store = getStore(sessions.Count +3); //+3 (for jumper, the AVG horizontal and SD horizontal)
} else {
*/
store = getStore(dataColumns +1); //jumper, AVG, SD
//}
if(toReport) {
reportString = prepareHeadersReport(columnsString);
} else {
treeview.Model = store;
prepareHeaders(columnsString);
}
}
public override void PrepareData()
{
string sessionString = obtainSessionSqlString(sessions, "jumpRj");
bool multisession = false;
/*
if(sessions.Count > 1) {
multisession = true;
}
*/
string operation = ""; // cannot be avg in this statistic
int myDataCols = 0;
int maxJumps = SqliteStat.ObtainMaxNumberOfJumps(sessionString);
processDataSimpleSession (
cleanDontWanted (
convertTCsTFsCombinedToIndexAVGSD (
SqliteStat.RjEvolution(sessionString, multisession,
operation, jumpType, showSex, maxJumps)),
statsJumpsType, limit),
false, dataColumns);
}
/*
* data come from RjEvolution like this:
myArray.Add (reader[0].ToString() + showSexString + showJumpTypeString +
returnSessionString + ":" + //session
Util.ChangeDecimalSeparator(reader[3].ToString()) + //index
returnFallString + //fall
allTCsTFsCombined //tc:tv:tc:tv...
);
* let's chage the allTCsTFsCombined to:
* AVG(index), SD (index)
* being index djIndex or Qindex
*/
private ArrayList convertTCsTFsCombinedToIndexAVGSD (ArrayList myDataCombined) {
int firstTCPos = 3;
ArrayList arrayConverted = new ArrayList();
string valuesListForAVG; //separated by '='
string valuesListForSD; //separated by ':'
double sumValues;
int count;
foreach (string row in myDataCombined) {
string [] strFull = row.Split(new char[] {':'});
valuesListForAVG = "";
valuesListForSD = "";
sumValues = 0;
count = 0;
string sepAVG = "";
string sepSD = "";
/*
* from the first TC in this serie TC:TF:TC:TF:...
* to the end of string
* calculate the index of every tc-tf pair
* if both values are different than "-"
* and prepare data for AVG and SD of index
*/
for (int i=firstTCPos; i+1 < strFull.Length; i+=2) {
if(strFull[i] != "-" && strFull[i+1] != "-") {
double myIndex = getIndex(
Convert.ToDouble(strFull[i+1]),
Convert.ToDouble(strFull[i]));
valuesListForAVG += sepAVG + myIndex.ToString();
valuesListForSD += sepSD + myIndex.ToString();
sumValues += myIndex;
count ++;
sepAVG = "=";
sepSD = ":";
}
}
double avg = Util.GetAverage(valuesListForAVG);
double sd = Util.CalculateSD(valuesListForSD, sumValues, count);
string rowConverted = strFull[0] + ":" + avg.ToString() + ":" + sd.ToString();
arrayConverted.Add(rowConverted);
}
return arrayConverted;
}
private double getIndex(double tf, double tc) {
if(indexType == Constants.RjIndexName)
return Util.GetDjIndex(tf, tc);
else
return Util.GetQIndex(tf, tc);
}
public override string ToString ()
{
string selectedValuesString = "";
if(statsJumpsType == 0) { //all jumps
selectedValuesString = allValuesString;
} else if(statsJumpsType == 1) { //limit
selectedValuesString = string.Format(Catalog.GetString("First {0} values"), limit);
} else if(statsJumpsType == 2) { //best of each jumper
selectedValuesString = string.Format(Catalog.GetString("Max {0} values of each jumper"), limit);
}
/* this option is not possible in this statistic
*
} else if(statsJumpsType == 3) { //avg of each jumper
selectedValuesString = avgValuesString;
}
*/
string [] strFull = sessions[0].ToString().Split(new char[] {':'});
string mySessionString = Catalog.GetString (" session ") +
strFull[0] + "(" + strFull[2] + ")";
string myFormula = "";
if(indexType == Constants.RjIndexName)
myFormula = Constants.RJAVGSDRjIndexName + " " + Constants.RjIndexOnlyFormula;
else
myFormula = Constants.RJAVGSDQIndexName + " " + Constants.QIndexOnlyFormula;
return string.Format(Catalog.GetString("{0} at average of jumps using {1} applied to {2} on {3}"),
selectedValuesString, myFormula, jumpType, mySessionString);
}
}
......@@ -267,14 +267,9 @@ public class StatRjEvolution : Stat
}
*/
string mySessionString = "";
if(sessions.Count > 1) {
mySessionString = Catalog.GetString (" various sessions ");
} else {
string [] strFull = sessions[0].ToString().Split(new char[] {':'});
mySessionString = Catalog.GetString (" session ") +
strFull[0] + "(" + strFull[2] + ")";
}
string [] strFull = sessions[0].ToString().Split(new char[] {':'});
string mySessionString = Catalog.GetString (" session ") +
strFull[0] + "(" + strFull[2] + ")";
string bestResalted = "";
if(numContinuous != -1) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment