/// <summary> /// Loads the shapes that are listed in the given database table /// and creates corresponding graphic elements. /// </summary> /// <param name="areaOfInterestTableRows"> /// Areas of interest table as /// a <see cref="DataGridViewRowCollection"/> /// </param> public void LoadShapesFromDataGridView(DataGridViewRowCollection areaOfInterestTableRows) { try { // Create aoi elements from data view this.AoiCollection = new VGElementCollection(); foreach (DataGridViewRow row in areaOfInterestTableRows) { if (!row.IsNewRow) { // retrieve shape parameters from cell values. var shapeName = row.Cells["colShapeName"].Value.ToString(); var strPtList = row.Cells["colShapePts"].Value.ToString(); Pen usedPen; Font usedFont; Color usedFontColor; VGAlignment usedAlignment; VGStyleGroup usedStyleGroup; var pointList = ObjectStringConverter.StringToPointFList(strPtList); var usedElementGroup = row.Cells["colShapeGroup"].Value.ToString(); switch (usedElementGroup) { case "Target": usedPen = this.TargetPen; usedFont = this.TargetFont; usedFontColor = this.TargetFontColor; usedStyleGroup = VGStyleGroup.AOI_TARGET; usedAlignment = this.TargetTextAlignment; break; case "SearchRect": usedPen = this.SearchRectPen; usedFont = this.SearchRectFont; usedFontColor = this.SearchRectFontColor; usedStyleGroup = VGStyleGroup.AOI_SEARCHRECT; usedAlignment = this.SearchRectTextAlignment; break; default: usedPen = this.DefaultPen; usedFont = this.DefaultFonts; usedFontColor = this.DefaultFontColor; usedStyleGroup = VGStyleGroup.AOI_NORMAL; usedAlignment = this.DefaultTextAlignment; break; } // Create the shape depending on ShapeType var boundingRect = new RectangleF(); switch (row.Cells["colShapeType"].Value.ToString()) { case "Rectangle": boundingRect.Location = pointList[0]; boundingRect.Width = pointList[2].X - pointList[0].X; boundingRect.Height = pointList[2].Y - pointList[0].Y; // Create Rect with defined stroke var newRect = new VGRectangle( this.hideAOIDescription ? ShapeDrawAction.Edge : ShapeDrawAction.NameAndEdge, usedPen, usedFont, usedFontColor, boundingRect, usedStyleGroup, shapeName, usedElementGroup); newRect.TextAlignment = usedAlignment; this.AoiCollection.Add(newRect); break; case "Ellipse": boundingRect.Location = pointList[0]; boundingRect.Width = pointList[2].X - pointList[0].X; boundingRect.Height = pointList[2].Y - pointList[0].Y; // Create Rect with defined stroke var newEllipse = new VGEllipse( this.hideAOIDescription ? ShapeDrawAction.Edge : ShapeDrawAction.NameAndEdge, usedPen, usedFont, usedFontColor, boundingRect, usedStyleGroup, shapeName, usedElementGroup); newEllipse.TextAlignment = usedAlignment; this.AoiCollection.Add(newEllipse); break; case "Polyline": // Create Polyline with defined stroke var newPolyline = new VGPolyline( this.hideAOIDescription ? ShapeDrawAction.Edge : ShapeDrawAction.NameAndEdge, usedPen, usedFont, usedFontColor, usedStyleGroup, shapeName, usedElementGroup); newPolyline.TextAlignment = usedAlignment; foreach (var point in pointList) { newPolyline.AddPt(point); } newPolyline.ClosePolyline(); this.AoiCollection.Add(newPolyline); break; } } } // Reset Elements (deselect and clear all) this.ResetPicture(); this.Elements.AddRange(this.AoiCollection); // If there were a selected element before updating, try // to select it again. if (this.SelectedElement != null) { foreach (VGElement element in this.Elements) { if (VGPolyline.Distance(element.Location, this.SelectedElement.Location) < 1) { this.SelectedElement = element; element.IsInEditMode = true; } } } this.DrawForeground(true); } catch (Exception ex) { ExceptionMethods.HandleException(ex); } }
/// <summary> /// Adds new point to given polyline, and truncates to <see cref="maxLengthPath"/> /// if DiscreteLength flag is set. /// </summary> /// <param name="polyline"> /// Polyline to modify /// </param> /// <param name="currPt"> /// new Position /// </param> /// <param name="discreteLength"> /// <strong>True</strong>, if path should be truncated, /// otherwise <strong>false</strong>. /// </param> /// <param name="time"> /// The <see cref="Int64"/> with the points time. /// </param> private void AddPtToPolyline(VGPolyline polyline, PointF currPt, bool discreteLength, long time) { // Add Point to Polyline polyline.AddPt(currPt); polyline.EndTime = time; // Switch to fixed length if choosen in UI if (discreteLength && (polyline.GetPointCount() > this.maxLengthPath)) { polyline.RemoveFirstPt(); } }
/// <summary> /// This method returns an default colored <see cref="VGElement"/> /// that represents the object in the database described by the three parameters /// </summary> /// <param name="shapeType">A <see cref="String"/> with the shape type Rectangle, Ellipse or Polyline</param> /// <param name="shapeName">A <see cref="String"/> with the shape name</param> /// <param name="shapeGroup">A <see cref="String"/> with the shapes group</param> /// <param name="strPtList">A <see cref="String"/> with the list of points to be converted /// with <see cref="ObjectStringConverter.StringToPointFList(String)"/></param> /// <returns>A <see cref="VGElement"/> that represents the object in the database described by the three parameters.</returns> public static VGElement GetVGElementFromDatabase( string shapeType, string shapeName, string shapeGroup, string strPtList) { // Create the shape depending on ShapeType RectangleF boundingRect = new RectangleF(); List<PointF> pointList = ObjectStringConverter.StringToPointFList(strPtList); switch (shapeType) { case "Rectangle": boundingRect.Location = pointList[0]; boundingRect.Width = pointList[2].X - pointList[0].X; boundingRect.Height = pointList[2].Y - pointList[0].Y; // Create Rect with defined stroke VGRectangle newRect = new VGRectangle( ShapeDrawAction.NameAndEdge, Pens.Red, SystemFonts.MenuFont, Color.Black, boundingRect, VGStyleGroup.None, shapeName, shapeGroup); newRect.TextAlignment = VGAlignment.Center; return newRect; case "Ellipse": boundingRect.Location = pointList[0]; boundingRect.Width = pointList[2].X - pointList[0].X; boundingRect.Height = pointList[2].Y - pointList[0].Y; // Create Rect with defined stroke VGEllipse newEllipse = new VGEllipse( ShapeDrawAction.NameAndEdge, Pens.Red, SystemFonts.MenuFont, Color.Black, boundingRect, VGStyleGroup.None, shapeName, shapeGroup); newEllipse.TextAlignment = VGAlignment.Center; return newEllipse; case "Polyline": // Create Polyline with defined stroke VGPolyline newPolyline = new VGPolyline( ShapeDrawAction.NameAndEdge, Pens.Red, SystemFonts.MenuFont, Color.Black, VGStyleGroup.None, shapeName, shapeGroup); newPolyline.TextAlignment = VGAlignment.Center; foreach (PointF point in pointList) { newPolyline.AddPt(point); } newPolyline.ClosePolyline(); boundingRect = newPolyline.Bounds; return newPolyline; } return null; }
/// <summary> /// This method converts the AOI table with areas of interest from the database /// into a list of <see cref="VGElement"/>s. /// </summary> /// <param name="aoiTable">The <see cref="DataTable"/> with the AOIs.</param> /// <returns>A <see cref="List{VGElement}"/> with the shapes.</returns> protected virtual VGElementCollection GetAOIElements(DataTable aoiTable) { Pen defaultPen = new Pen(Properties.Settings.Default.AOIStandardColor, Properties.Settings.Default.AOIStandardWidth); Pen targetPen = new Pen(Properties.Settings.Default.AOITargetColor, Properties.Settings.Default.AOITargetWidth); Pen searchRectPen = new Pen(Properties.Settings.Default.AOISearchRectColor, Properties.Settings.Default.AOISearchRectWidth); Font defaultFont = (Font)Properties.Settings.Default.AOIStandardFont.Clone(); Font targetFont = (Font)Properties.Settings.Default.AOITargetFont.Clone(); Font searchRectFont = (Font)Properties.Settings.Default.AOISearchRectFont.Clone(); Color defaultFontColor = Properties.Settings.Default.AOIStandardFontColor; Color targetFontColor = Properties.Settings.Default.AOITargetFontColor; Color searchRectFontColor = Properties.Settings.Default.AOISearchRectFontColor; VGElementCollection aoiList = new VGElementCollection(); int counter = 0; try { foreach (DataRow row in aoiTable.Rows) { string strPtList = row["ShapePts"].ToString(); string shapeName = row["ShapeName"].ToString(); Pen usedPen = defaultPen; Font usedFont = defaultFont; Color usedFontColor = defaultFontColor; VGStyleGroup usedStyleGroup = VGStyleGroup.AOI_NORMAL; List<PointF> pointList = ObjectStringConverter.StringToPointFList(strPtList); string usedElementGroup = row["ShapeGroup"].ToString(); switch (usedElementGroup) { case "Target": usedPen = targetPen; usedFont = targetFont; usedFontColor = targetFontColor; usedStyleGroup = VGStyleGroup.SCA_GRID_AOI; break; case "SearchRect": usedPen = searchRectPen; usedFont = searchRectFont; usedFontColor = searchRectFontColor; usedStyleGroup = VGStyleGroup.SCA_GRID_AOI; break; default: usedPen = defaultPen; usedFont = defaultFont; usedFontColor = defaultFontColor; usedStyleGroup = VGStyleGroup.SCA_GRID_AOI; break; } // Create the shape depending on ShapeType RectangleF boundingRect = new RectangleF(); switch (row["ShapeType"].ToString()) { case "Rectangle": boundingRect.Location = pointList[0]; boundingRect.Width = pointList[2].X - pointList[0].X; boundingRect.Height = pointList[2].Y - pointList[0].Y; // Create Rect with defined stroke VGRectangle newRect = new VGRectangle( ShapeDrawAction.NameAndEdge, usedPen, usedFont, usedFontColor, boundingRect, usedStyleGroup, shapeName, usedElementGroup); aoiList.Add(newRect); break; case "Ellipse": boundingRect.Location = pointList[0]; boundingRect.Width = pointList[2].X - pointList[0].X; boundingRect.Height = pointList[2].Y - pointList[0].Y; // Create Rect with defined stroke VGEllipse newEllipse = new VGEllipse( ShapeDrawAction.NameAndEdge, usedPen, usedFont, usedFontColor, boundingRect, usedStyleGroup, shapeName, usedElementGroup); aoiList.Add(newEllipse); break; case "Polyline": // Create Polyline with defined stroke VGPolyline newPolyline = new VGPolyline( ShapeDrawAction.NameAndEdge, usedPen, usedFont, usedFontColor, usedStyleGroup, shapeName, usedElementGroup); foreach (PointF point in pointList) { newPolyline.AddPt(point); } newPolyline.ClosePolyline(); aoiList.Add(newPolyline); boundingRect = newPolyline.Bounds; break; } counter++; } } catch (Exception ex) { ExceptionMethods.HandleException(ex); } return aoiList; }
/// <summary> /// This static method calculates the sum of fixation connections, /// which is a gaze path length. /// </summary> /// <param name="fixationTable">A <see cref="DataTable"/> with the fixations /// to use.</param> /// <returns>A <see cref="Single"/> with the path length in pixel.</returns> private static float CalcPathLengthOfFixationConnections(DataTable fixationTable) { // Fixation PathLength // no fixation available float pathLengthGaze = -1f; VGPolyline polylineGaze = new VGPolyline(ShapeDrawAction.Edge, Pens.Green); foreach (DataRow row in fixationTable.Rows) { float gazeX = !row.IsNull("PosX") ? Convert.ToSingle(row["PosX"]) : 0; float gazeY = !row.IsNull("PosY") ? Convert.ToSingle(row["PosY"]) : 0; if (gazeX != 0 || gazeY != 0) { polylineGaze.AddPt(new PointF(gazeX, gazeY)); } } if (polylineGaze.GetPointCount() >= 2) { // Connections available pathLengthGaze = polylineGaze.GetLength(); } else if (polylineGaze.GetPointCount() == 1) { // Only one fixation, so no connections pathLengthGaze = 0; } return pathLengthGaze; }
/// <summary> /// This static method calculates the raw data related variables as there /// are distance of gaze and mouse path along with loss and out of /// monitor values. /// </summary> /// <param name="subjectName">A <see cref="string"/> with the subject name.</param> /// <param name="trialSequence">An <see cref="int"/> with the trial sequence number.</param> /// <param name="countBlinkLoss">Ref. Counts the samples the are lost due to blinks.</param> /// <param name="countOutOfMonitorLoss">Ref. Counts the samples the are lost due to out of monitor samples.</param> /// <param name="pathLengthMouse">Ref. Returns the path length of the mouse path.</param> /// <param name="averageDistance">Ref. Returns the average distance of gaze and mouse path in pixel.</param> /// <param name="countSamples">Ref. Counts the number of samples.</param> private static void CalcRawDataRelatedVariables( string subjectName, int trialSequence, ref int countBlinkLoss, ref int countOutOfMonitorLoss, ref float pathLengthMouse, ref float averageDistance, ref int countSamples) { // Get RawData DataTable rawDataTable = Queries.GetRawDataBySubjectAndTrialSequenceWithoutEvents(subjectName, trialSequence); // In this section only mouse polyline is created, // because the gaze path length is calculated as the // distance between fixations to avoid // including microsaccade movements. VGPolyline polylineMouse = new VGPolyline(ShapeDrawAction.Edge, Pens.Red); float sumDistance = 0; int distancesCount = 0; // Loop RawData and drawPolyline foreach (DataRow row in rawDataTable.Rows) { PointF? newGazePoint; SampleValidity isGazeValidData = Queries.GetGazeData( row, Document.ActiveDocument.PresentationSize, out newGazePoint); switch (isGazeValidData) { case SampleValidity.Valid: break; case SampleValidity.Empty: countBlinkLoss++; break; case SampleValidity.Null: countBlinkLoss++; break; case SampleValidity.OutOfStimulus: countOutOfMonitorLoss++; break; } PointF? newMousePoint; SampleValidity isMouseValidData = Queries.GetMouseData( row, Document.ActiveDocument.PresentationSize, out newMousePoint); switch (isMouseValidData) { case SampleValidity.Valid: case SampleValidity.Empty: case SampleValidity.OutOfStimulus: // mouse is always detected and never out of screen polylineMouse.AddPt(newMousePoint.Value); break; case SampleValidity.Null: break; } // Calculate Distance of Gaze And Mouse Path if (isGazeValidData == SampleValidity.Valid && (isMouseValidData == SampleValidity.Valid || isMouseValidData == SampleValidity.Empty)) { sumDistance += VGPolyline.Distance(newGazePoint.Value, newMousePoint.Value); distancesCount++; } } if (polylineMouse.GetPointCount() >= 2) { pathLengthMouse = polylineMouse.GetLength(); } else if (polylineMouse.GetPointCount() == 1) { pathLengthMouse = 0; // No Movement in MouseData } if (distancesCount > 0) { averageDistance = sumDistance / distancesCount; } else { averageDistance = -1; } countSamples = rawDataTable.Rows.Count; rawDataTable.Dispose(); }