[chronojump] Several improvements on Cairo graphs: clickable show nearest point



commit caba4ca5c3ff02429edbf629088f35db69b31d4f
Author: Xavier de Blas <xaviblas gmail com>
Date:   Mon Jan 13 18:25:04 2020 +0100

    Several improvements on Cairo graphs: clickable show nearest point

 glade/app1.glade                      |  33 +++++---
 src/gui/app1/jumpsDjOptimalFall.cs    |  22 +++++-
 src/gui/app1/jumpsEvolution.cs        |  23 +++++-
 src/gui/app1/jumpsWeightFVProfile.cs  |  24 +++++-
 src/gui/cairo/jumpsDjOptimalFall.cs   |   7 +-
 src/gui/cairo/jumpsEvolution.cs       |   6 +-
 src/gui/cairo/jumpsWeightFVProfile.cs |   7 +-
 src/gui/cairo/xy.cs                   | 138 +++++++++++++++++++++++++++++-----
 8 files changed, 217 insertions(+), 43 deletions(-)
---
diff --git a/glade/app1.glade b/glade/app1.glade
index 9f769699..dc23d1b7 100644
--- a/glade/app1.glade
+++ b/glade/app1.glade
@@ -18843,6 +18843,7 @@ Concentric</property>
                                                           <widget class="GtkDrawingArea" 
id="drawingarea_jumps_dj_optimal_fall">
                                                             <property name="visible">True</property>
                                                             <property name="can_focus">False</property>
+                                                            <signal name="button_press_event" 
handler="on_drawingarea_jumps_dj_optimal_fall_button_press_event" swapped="no"/>
                                                             <signal name="expose_event" 
handler="on_drawingarea_jumps_dj_optimal_fall_expose_event" swapped="no"/>
                                                           </widget>
                                                           <packing>
@@ -18983,6 +18984,7 @@ Concentric</property>
                                                           <widget class="GtkDrawingArea" 
id="drawingarea_jumps_weight_fv_profile">
                                                             <property name="visible">True</property>
                                                             <property name="can_focus">False</property>
+                                                            <signal name="button_press_event" 
handler="on_drawingarea_jumps_weight_fv_profile_button_press_event" swapped="no"/>
                                                             <signal name="expose_event" 
handler="on_drawingarea_jumps_weight_fv_profile_expose_event" swapped="no"/>
                                                           </widget>
                                                           <packing>
@@ -19124,6 +19126,7 @@ Concentric</property>
                                                           <widget class="GtkDrawingArea" 
id="drawingarea_jumps_evolution">
                                                             <property name="visible">True</property>
                                                             <property name="can_focus">False</property>
+                                                            <signal name="button_press_event" 
handler="on_drawingarea_jumps_evolution_button_press_event" swapped="no"/>
                                                             <signal name="expose_event" 
handler="on_drawingarea_jumps_evolution_expose_event" swapped="no"/>
                                                           </widget>
                                                           <packing>
@@ -22800,6 +22803,9 @@ Concentric</property>
                                                             <child>
                                                             <placeholder/>
                                                             </child>
+                                                            <child>
+                                                            <placeholder/>
+                                                            </child>
                                                             </widget>
                                                             <packing>
                                                             <property name="expand">False</property>
@@ -25047,6 +25053,18 @@ Concentric</property>
                                                             <property name="can_focus">False</property>
                                                             <property name="spacing">6</property>
                                                             <child>
+                                                            <widget class="GtkLabel" 
id="label_video_encoder_tests_will_be_filmed">
+                                                            <property name="can_focus">False</property>
+                                                            <property name="label" translatable="yes">Tests 
will be filmed</property>
+                                                            </widget>
+                                                            <packing>
+                                                            <property name="expand">False</property>
+                                                            <property name="fill">False</property>
+                                                            <property name="pack_type">end</property>
+                                                            <property name="position">0</property>
+                                                            </packing>
+                                                            </child>
+                                                            <child>
                                                             <widget class="GtkHBox" 
id="hbox_video_encoder_capturing">
                                                             <property name="can_focus">False</property>
                                                             <property name="spacing">4</property>
@@ -25083,18 +25101,6 @@ Concentric</property>
                                                             </packing>
                                                             </child>
                                                             <child>
-                                                            <widget class="GtkLabel" 
id="label_video_encoder_tests_will_be_filmed">
-                                                            <property name="can_focus">False</property>
-                                                            <property name="label" translatable="yes">Tests 
will be filmed</property>
-                                                            </widget>
-                                                            <packing>
-                                                            <property name="expand">False</property>
-                                                            <property name="fill">False</property>
-                                                            <property name="pack_type">end</property>
-                                                            <property name="position">0</property>
-                                                            </packing>
-                                                            </child>
-                                                            <child>
                                                             <widget class="GtkHBox" 
id="hbox_video_encoder_no_capturing">
                                                             <property name="visible">True</property>
                                                             <property name="can_focus">False</property>
@@ -32342,6 +32348,9 @@ then click this button.</property>
                                                             <child>
                                                             <placeholder/>
                                                             </child>
+                                                            <child>
+                                                            <placeholder/>
+                                                            </child>
                                                             </widget>
                                                             <packing>
                                                             <property name="expand">False</property>
diff --git a/src/gui/app1/jumpsDjOptimalFall.cs b/src/gui/app1/jumpsDjOptimalFall.cs
index 581f21de..a9766b64 100644
--- a/src/gui/app1/jumpsDjOptimalFall.cs
+++ b/src/gui/app1/jumpsDjOptimalFall.cs
@@ -34,6 +34,7 @@ public partial class ChronoJumpWindow
        [Widget] Gtk.Button button_jumps_dj_optimal_fall_save_image;
 
        JumpsDjOptimalFall jumpsDjOptimalFall;
+       JumpsDjOptimalFallGraph jumpsDjOptimalFallGraph;
        CjComboSelectJumps comboSelectJumpsDjOptimalFall;
 
        // combo (start)
@@ -89,7 +90,7 @@ public partial class ChronoJumpWindow
 
                } else {
                        //regular constructor
-                       JumpsDjOptimalFallGraph jdofg = new JumpsDjOptimalFallGraph(
+                       jumpsDjOptimalFallGraph = new JumpsDjOptimalFallGraph(
                                        jumpsDjOptimalFall.Point_l,
                                        jumpsDjOptimalFall.Coefs,
                                        jumpsDjOptimalFall.ParaboleType, //model
@@ -97,17 +98,34 @@ public partial class ChronoJumpWindow
                                        jumpsDjOptimalFall.GetMaxValue(),
                                        drawingarea_jumps_dj_optimal_fall,
                                        currentPerson.Name, jumpType, currentSession.DateShort);
-                       jdofg.Do();
+                       jumpsDjOptimalFallGraph.Do();
 
                        button_jumps_dj_optimal_fall_save_image.Sensitive = true;
                }
        }
        private void on_drawingarea_jumps_dj_optimal_fall_expose_event (object o, ExposeEventArgs args) 
        {
+               //needed to have mouse clicks at: on_drawingarea_jumps_weight_fv_profile_button_press_event ()
+               drawingarea_jumps_dj_optimal_fall.AddEvents((int) (Gdk.EventMask.ButtonPressMask | 
Gdk.EventMask.ButtonReleaseMask));
+
                jumpsDjOptimalFallDo(false); //do not calculate data
                //data is calculated on switch page (at notebook_capture_analyze) or on change person
        }
 
+       private void on_drawingarea_jumps_dj_optimal_fall_button_press_event (object o, ButtonPressEventArgs 
args)
+       {
+               //if there is no data and nothing to show, nothing to press, and also this is null
+               if(jumpsDjOptimalFallGraph == null)
+                       return;
+
+               LogB.Information("Button press done!");
+
+               //redo the graph to delete previous rectangles of previous mouse clicks
+               jumpsDjOptimalFallGraph.Do();
+               LogB.Information(string.Format("Mouse X: {0}; Mouse Y: {1}", args.Event.X, args.Event.Y));
+               jumpsDjOptimalFallGraph.CalculateAndWriteRealXY(args.Event.X, args.Event.Y);
+       }
+
        private void on_button_jumps_dj_optimal_fall_save_image_clicked (object o, EventArgs args)
        {
                checkFile(Constants.CheckFileOp.JUMPS_DJ_OPTIMAL_FALL_SAVE_IMAGE);
diff --git a/src/gui/app1/jumpsEvolution.cs b/src/gui/app1/jumpsEvolution.cs
index c3f100a0..ad765594 100644
--- a/src/gui/app1/jumpsEvolution.cs
+++ b/src/gui/app1/jumpsEvolution.cs
@@ -34,6 +34,7 @@ public partial class ChronoJumpWindow
        [Widget] Gtk.Button button_jumps_evolution_save_image;
 
        JumpsEvolution jumpsEvolution;
+       JumpsEvolutionGraph jumpsEvolutionGraph;
        CjComboSelectJumps comboSelectJumpsEvolution;
 
        // combo (start)
@@ -89,24 +90,40 @@ public partial class ChronoJumpWindow
 
                } else {
                        //regular constructor
-                       JumpsEvolutionGraph jeg = new JumpsEvolutionGraph(
+                       jumpsEvolutionGraph = new JumpsEvolutionGraph(
                                        jumpsEvolution.Point_l,
                                        jumpsEvolution.Slope,
                                        jumpsEvolution.Intercept,
                                        drawingarea_jumps_evolution,
                                        currentPerson.Name, jumpType, currentSession.DateShort);
-                       jeg.Do();
+                       jumpsEvolutionGraph.Do();
 
                        button_jumps_evolution_save_image.Sensitive = true;
                }
        }
        private void on_drawingarea_jumps_evolution_expose_event (object o, ExposeEventArgs args) 
        {
+               //needed to have mouse clicks at: on_drawingarea_jumps_weight_fv_profile_button_press_event ()
+               drawingarea_jumps_evolution.AddEvents((int) (Gdk.EventMask.ButtonPressMask | 
Gdk.EventMask.ButtonReleaseMask));
+
                jumpsEvolutionDo(false); //do not calculate data
                //data is calculated on switch page (at notebook_capture_analyze) or on change person
        }
 
-       //TODO
+       private void on_drawingarea_jumps_evolution_button_press_event (object o, ButtonPressEventArgs args)
+       {
+               //if there is no data and nothing to show, nothing to press, and also this is null
+               if(jumpsEvolutionGraph == null)
+                       return;
+
+               LogB.Information("Button press done!");
+
+               //redo the graph to delete previous rectangles of previous mouse clicks
+               jumpsEvolutionGraph.Do();
+               LogB.Information(string.Format("Mouse X: {0}; Mouse Y: {1}", args.Event.X, args.Event.Y));
+               jumpsEvolutionGraph.CalculateAndWriteRealXY(args.Event.X, args.Event.Y);
+       }
+
        private void on_button_jumps_evolution_save_image_clicked (object o, EventArgs args)
        {
                checkFile(Constants.CheckFileOp.JUMPS_EVOLUTION_SAVE_IMAGE);
diff --git a/src/gui/app1/jumpsWeightFVProfile.cs b/src/gui/app1/jumpsWeightFVProfile.cs
index 53bdfbf7..e1d681ff 100644
--- a/src/gui/app1/jumpsWeightFVProfile.cs
+++ b/src/gui/app1/jumpsWeightFVProfile.cs
@@ -34,6 +34,7 @@ public partial class ChronoJumpWindow
        [Widget] Gtk.Button button_jumps_weight_fv_profile_save_image;
 
        JumpsWeightFVProfile jumpsWeightFVProfile;
+       JumpsWeightFVProfileGraph jumpsWeightFVProfileGraph;
        CjComboSelectJumps comboSelectJumpsWeightFVProfile;
 
        // combo (start)
@@ -109,24 +110,43 @@ public partial class ChronoJumpWindow
                                        //currentPerson.Name, jumpType, currentSession.DateShort);
                } else {
                        //regular constructor
-                       JumpsWeightFVProfileGraph jwfv = new JumpsWeightFVProfileGraph(
+                       jumpsWeightFVProfileGraph = new JumpsWeightFVProfileGraph(
                                        jumpsWeightFVProfile.Point_l,
                                        jumpsWeightFVProfile.Slope,
                                        jumpsWeightFVProfile.Intercept,
                                        drawingarea_jumps_weight_fv_profile,
                                        currentPerson.Name, //jumpType,
                                        currentSession.DateShort);
-                       jwfv.Do();
+                       jumpsWeightFVProfileGraph.Do();
 
                        button_jumps_weight_fv_profile_save_image.Sensitive = true;
                }
        }
        private void on_drawingarea_jumps_weight_fv_profile_expose_event (object o, ExposeEventArgs args) 
        {
+               //needed to have mouse clicks at: on_drawingarea_jumps_weight_fv_profile_button_press_event ()
+               drawingarea_jumps_weight_fv_profile.AddEvents((int) (Gdk.EventMask.ButtonPressMask | 
Gdk.EventMask.ButtonReleaseMask));
+
                jumpsWeightFVProfileDo(false); //do not calculate data
                //data is calculated on switch page (at notebook_capture_analyze) or on change person
        }
 
+       private void on_drawingarea_jumps_weight_fv_profile_button_press_event (object o, 
ButtonPressEventArgs args)
+       {
+               //if there is no data and nothing to show, nothing to press, and also this is null
+               if(jumpsWeightFVProfileGraph == null)
+                       return;
+
+               LogB.Information("Button press done!");
+
+               //redo the graph to delete previous rectangles of previous mouse clicks
+               jumpsWeightFVProfileGraph.Do();
+               LogB.Information(string.Format("Mouse X: {0}; Mouse Y: {1}", args.Event.X, args.Event.Y));
+               //LogB.Information(string.Format("Real X: {0}; Real Y: {1}",
+               //                      jumpsWeightFVProfileGraph.CalculateAndWriteRealXY(args.Event.X, 
args.Event.Y)));
+               jumpsWeightFVProfileGraph.CalculateAndWriteRealXY(args.Event.X, args.Event.Y);
+       }
+
        private void on_button_jumps_weight_fv_profile_save_image_clicked (object o, EventArgs args)
        {
                checkFile(Constants.CheckFileOp.JUMPS_WEIGHT_FV_PROFILE_SAVE_IMAGE);
diff --git a/src/gui/cairo/jumpsDjOptimalFall.cs b/src/gui/cairo/jumpsDjOptimalFall.cs
index b03f6447..676652e5 100644
--- a/src/gui/cairo/jumpsDjOptimalFall.cs
+++ b/src/gui/cairo/jumpsDjOptimalFall.cs
@@ -61,8 +61,10 @@ public class JumpsDjOptimalFallGraph : CairoXY
                this.jumpType = jumpType;
                this.date = date;
 
-               axisYLabel = "Height (cm)";
-               axisXLabel = "Fall (cm)";
+               xVariable = "Fall";
+               yVariable = "Height";
+               xUnits = "cm";
+               yUnits = "cm";
        }
 
        public override void Do()
@@ -86,6 +88,7 @@ public class JumpsDjOptimalFallGraph : CairoXY
                        {
                                plotPredictedMaxPoint();
                                writeTextPredictedPoint();
+                               predictedPointDone = true;
                        }
                        else
                                writeTextConcaveParabole();
diff --git a/src/gui/cairo/jumpsEvolution.cs b/src/gui/cairo/jumpsEvolution.cs
index b1a17c6a..020de266 100644
--- a/src/gui/cairo/jumpsEvolution.cs
+++ b/src/gui/cairo/jumpsEvolution.cs
@@ -54,8 +54,10 @@ public class JumpsEvolutionGraph : CairoXY
                this.jumpType = jumpType;
                this.date = date;
 
-               axisYLabel = "Height (cm)";
-               axisXLabel = "Date";
+               xVariable = "Date";
+               yVariable = "Height";
+               xUnits = "";
+               yUnits = "cm";
        }
 
        public override void Do()
diff --git a/src/gui/cairo/jumpsWeightFVProfile.cs b/src/gui/cairo/jumpsWeightFVProfile.cs
index b6607288..1edccfb3 100644
--- a/src/gui/cairo/jumpsWeightFVProfile.cs
+++ b/src/gui/cairo/jumpsWeightFVProfile.cs
@@ -66,8 +66,11 @@ public class JumpsWeightFVProfileGraph : CairoXY
                this.date = date;
 
                outerMargins = 50; //blank space outside the axis
-               axisYLabel = "Force (N)";
-               axisXLabel = "Speed (m/s)";
+
+               xVariable = "Speed";
+               yVariable = "Force";
+               xUnits = "m/s";
+               yUnits = "N";
        }
 
        public override void Do()
diff --git a/src/gui/cairo/xy.cs b/src/gui/cairo/xy.cs
index baabea95..54626602 100644
--- a/src/gui/cairo/xy.cs
+++ b/src/gui/cairo/xy.cs
@@ -28,6 +28,7 @@ public abstract class CairoXY
 {
        //used on construction
        protected List<Point> point_l;
+       protected bool predictedPointDone;
 
        //regression line straight
        protected double slope;
@@ -46,8 +47,10 @@ public abstract class CairoXY
 
        protected Cairo.Context g;
        protected const int textHeight = 12;
-       protected string axisYLabel = "";
-       protected string axisXLabel = "";
+       protected string xVariable = "";
+       protected string yVariable = "";
+       protected string xUnits = "";
+       protected string yUnits = "";
 
        protected double minX = 1000000;
        protected double maxX = 0;
@@ -58,12 +61,15 @@ public abstract class CairoXY
        double absoluteMaxY;
        protected int graphWidth;
        protected int graphHeight;
+
+       Cairo.Color black;
+       Cairo.Color white;
        Cairo.Color red;
        Cairo.Color blue;
 
        //for all 4 sides
-       protected int outerMargins = 40; //blank space outside the axis
-       protected int innerMargins = 30; //space between the axis and the real coordinates
+       protected int outerMargins = 40; //blank space outside the axis.
+       protected int innerMargins = 30; //space between the axis and the real coordinates.
        int totalMargins;
 
        public abstract void Do();
@@ -89,8 +95,12 @@ public abstract class CairoXY
                g.SelectFontFace("Helvetica", Cairo.FontSlant.Normal, Cairo.FontWeight.Normal);
                g.SetFontSize(textHeight);
 
+               black = colorFromRGB(0,0,0);
+               white = colorFromRGB(255,255,255);
                red = colorFromRGB(200,0,0);
                blue = colorFromRGB(178, 223, 238); //lightblue
+
+               predictedPointDone = false;
        }
 
        protected void findPointMaximums()
@@ -157,12 +167,27 @@ public abstract class CairoXY
                g.LineTo(outerMargins, graphHeight - outerMargins);
                g.LineTo(graphWidth - outerMargins, graphHeight - outerMargins);
                g.Stroke ();
-               printText(2, Convert.ToInt32(outerMargins/2), 0, textHeight, axisYLabel, g, false);
-               printText(graphWidth - Convert.ToInt32(outerMargins/2), graphHeight - outerMargins, 0, 
textHeight, axisXLabel, g, false);
+               printText(2, Convert.ToInt32(outerMargins/2), 0, textHeight, getYAxisLabel(), g, false);
+               printText(graphWidth - Convert.ToInt32(outerMargins/2), graphHeight - outerMargins, 0, 
textHeight, getXAxisLabel(), g, false);
 
                paintGrid (minX, absoluteMaxX, minY, absoluteMaxY, 5, gridType);
        }
 
+       private string getXAxisLabel()
+       {
+               return getAxisLabel(xVariable, xUnits);
+       }
+       private string getYAxisLabel()
+       {
+               return getAxisLabel(yVariable, yUnits);
+       }
+       private string getAxisLabel(string variable, string units)
+       {
+               if(units == "")
+                       return variable;
+               return string.Format("{0} ({1})", variable, units);
+       }
+
        protected enum predictedLineTypes { STRAIGHT, PARABOLE }
        protected void plotPredictedLine(predictedLineTypes plt)
        {
@@ -247,9 +272,9 @@ public abstract class CairoXY
                        */
 
                        LogB.Information(string.Format("xgraph: {0} corresponds to x real point: {1}", xgraph,
-                                               calculateRealX(xgraph, graphWidth, absoluteMaxX, minX, 
totalMargins, totalMargins)));
+                                               calculateRealX(xgraph)));
                        LogB.Information(string.Format("ygraph: {0} corresponds to y real point: {1}", ygraph,
-                                               calculateRealY(ygraph, graphHeight, absoluteMaxY, minY, 
totalMargins, totalMargins)));
+                                               calculateRealY(ygraph)));
                }
                getMinMaxXDrawable(graphWidth, absoluteMaxX, minX, totalMargins, totalMargins);
        }
@@ -310,6 +335,80 @@ public abstract class CairoXY
                        g.SelectFontFace("Helvetica", Cairo.FontSlant.Normal, Cairo.FontWeight.Normal);
        }
 
+       protected void writeCoordinatesOfMouseClick(double graphX, double graphY, double realX, double realY)
+       {
+               // 1) need to do this because context has been disposed
+               LogB.Information(string.Format("g == null: {0}", (g = null)));
+               if(g == null)
+                       g = Gdk.CairoHelper.Create (area.GdkWindow);
+
+
+               int line = 4;
+               /*
+                * This is not needed because graph is re-done at each mouse click
+                *
+               //rectangle to erase previous values
+               g.Color = white;
+               g.Rectangle(graphWidth + 1, Convert.ToInt32(graphHeight/2) + textHeight*2*line - textHeight,
+                               area.Allocation.Width -1, textHeight*8);
+               g.Fill();
+               g.Color = black;
+               */
+
+               // 2) exit if out of graph area
+               LogB.Information(string.Format("graphX: {0}; graphY: {1}", graphX, graphY));
+               if(
+                               graphX < outerMargins || graphX > graphWidth - outerMargins ||
+                               graphY < outerMargins || graphY > graphHeight - outerMargins )
+                       return;
+
+               /* optional show real mouse click
+               //write text (of clicked point)
+               writeTextAtRight(line, "X: " + Util.TrimDecimals(realX, 2), false);
+               writeTextAtRight(line +1, "Y: " + Util.TrimDecimals(realY, 2), false);
+               */
+
+               // 3) find closest point (including predicted point if any)
+               Point pClosest = findClosestRealPoint(realX, realY);
+
+               // 4) write text at right
+               writeTextAtRight(line, "Selected:", false);
+               writeTextAtRight(line +1, string.Format("{0}: {1} {2}", xVariable, 
Util.TrimDecimals(pClosest.X, 2), xUnits), false);
+               writeTextAtRight(line +2, string.Format("{0}: {1} {2}", yVariable, 
Util.TrimDecimals(pClosest.Y, 2), yUnits), false);
+
+               // 5) paint rectangle around that point
+               g.Color = red;
+               g.Rectangle(
+                               calculatePaintX(pClosest.X,
+                                       graphWidth, absoluteMaxX, minX, totalMargins, totalMargins) -12,
+                               calculatePaintY(pClosest.Y,
+                                       graphHeight, absoluteMaxY, minY, totalMargins, totalMargins) -12,
+                               24, 24);
+               g.Stroke();
+               g.Color = black;
+       }
+
+       private Point findClosestRealPoint(double realX, double realY)
+       {
+               double distMin = 10000000;
+               Point pClosest = point_l[0];
+               foreach(Point p in point_l)
+               {
+                       double dist = Math.Sqrt(Math.Pow(realX - p.X, 2) + Math.Pow(realY - p.Y, 2));
+                       if(dist < distMin)
+                       {
+                               distMin = dist;
+                               pClosest = p;
+                       }
+               }
+
+               //also check predicted point if exits
+               if(predictedPointDone && Math.Sqrt(Math.Pow(realX - xAtMMaxY, 2) + Math.Pow(realY - yAtMMaxY, 
2)) < distMin)
+                       pClosest = new Point(xAtMMaxY, yAtMMaxY);
+
+               return pClosest;
+       }
+
        protected void endGraph()
        {
                g.GetTarget().Dispose ();
@@ -332,7 +431,7 @@ public abstract class CairoXY
                if(gridType != gridTypes.HORIZONTALLINES)
                        for(double i = minX; i <= maxX *1.5 ; i += stepX)
                        {
-                               int xtemp = Convert.ToInt32(calculatePaintX(i, graphWidth, maxX, minX, 
outerMargins + innerMargins, outerMargins + innerMargins));
+                               int xtemp = Convert.ToInt32(calculatePaintX(i, graphWidth, maxX, minX, 
totalMargins, totalMargins));
                                if(xtemp < outerMargins || xtemp > graphWidth - outerMargins)
                                        continue;
 
@@ -342,7 +441,7 @@ public abstract class CairoXY
                if(gridType != gridTypes.VERTICALLINES)
                        for(double i = minY; i <= maxY *1.5 ; i += stepY)
                        {
-                               int ytemp = Convert.ToInt32(calculatePaintY(i, graphHeight, maxY, minY, 
outerMargins + innerMargins, outerMargins + innerMargins));
+                               int ytemp = Convert.ToInt32(calculatePaintY(i, graphHeight, maxY, minY, 
totalMargins, totalMargins));
                                if(ytemp < outerMargins || ytemp > graphHeight - outerMargins)
                                        continue;
 
@@ -399,21 +498,24 @@ public abstract class CairoXY
                 return alto - bottomMargin - ((realY - minValue) * (alto - topMargin - bottomMargin) / 
(maxValue - minValue));
         }
 
-       //get the real point of a graph point
-       private double calculateRealX (double graphX, int ancho, double maxValue, double minValue, int 
rightMargin, int leftMargin)
+       private double calculateRealX (double graphX)
        {
-                return minValue + ( (graphX - leftMargin) * (maxValue - minValue) / (ancho - rightMargin - 
leftMargin) );
-        }
-       private double calculateRealY (double graphY, int alto, double maxValue, double minValue, int 
topMargin, int bottomMargin)
+                return minX + ( (graphX - totalMargins) * (absoluteMaxX - minX) / (graphWidth - totalMargins 
- totalMargins) );
+       }
+       private double calculateRealY (double graphY)
        {
-                return minValue + (- graphY + alto - bottomMargin) * (maxValue - minValue) / (alto - 
topMargin - bottomMargin);
+               return minY - (graphY - graphHeight + totalMargins) * (absoluteMaxY - minY) / (graphHeight - 
totalMargins - totalMargins);
         }
+       public void CalculateAndWriteRealXY (double graphX, double graphY)
+       {
+               writeCoordinatesOfMouseClick(graphX, graphY, calculateRealX(graphX), calculateRealY(graphY));
+       }
 
        private void getMinMaxXDrawable(int ancho, double maxValue, double minValue, int rightMargin, int 
leftMargin)
        {
                LogB.Information(string.Format("Real points fitting on graph margins:  {0} , {1}",
-                                       calculateRealX(outerMargins, graphWidth, absoluteMaxX, minX, 
totalMargins, totalMargins),
-                                       calculateRealX(graphWidth - outerMargins, graphWidth, absoluteMaxX, 
minX, totalMargins, totalMargins)
+                                       calculateRealX(totalMargins),
+                                       calculateRealX(graphWidth - totalMargins)
                                        ));
        }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]