/// <summary> /// Gets the panel at the specied offset. /// </summary> /// <param name="offset">Offset at which panel needs to be determined.</param> /// <returns>Panel at the specified offset.</returns> protected virtual PanelWrapper GetPanel(double offset) { PanelWrapper panel = new PanelWrapper(); panel.Height = this.DynamicMainLayerViewport.ActualHeight; panel.Width = this.DynamicMainLayerViewport.ActualWidth; TextBlock tb = new TextBlock(); tb.HorizontalAlignment = HorizontalAlignment.Center; tb.FontSize = 70; tb.Text = offset.ToString(System.Globalization.CultureInfo.CurrentCulture); panel.Children.Add(tb); this.DynamicMainLayerViewport.Children.Add(panel); return(panel); }
/// <summary> /// Plots the graph at specified offset. /// </summary> /// <param name="offset">Offset at which to plot the graph.</param> /// <returns>Returns the panel at the specified offset.</returns> protected PanelWrapper DrawGraph(long offset) { PanelWrapper panel = null; panel = new PanelWrapper(); panel.Height = this.DynamicMainLayerViewport.ActualHeight; panel.Width = this.DynamicMainLayerViewport.ActualWidth; this.DynamicMainLayer = this.DynamicMainLayerTemplate.LoadContent() as FrameworkElement; panel.Children.Add(this.DynamicMainLayer); this.DynamicMainLayerViewport.Children.Add(panel); panel.Tag = offset; return(panel); }
/// <summary> /// Processes the panel. /// </summary> /// <param name="panel">The panel.</param> /// <param name="panelNumber">The panel number.</param> private void ProcessPanel(PanelWrapper panel, int panelNumber) { this.CurrentWorkingPanel = panel; if (this.ShowSeamBoundaries) { panel.AddSeamBoundary(); } if (panel.Tag != null) { if (panel.Children.Count < 1) { return; } Grid elementDynamicMainLayer = panel.Children[0] as Grid; if (null == elementDynamicMainLayer || elementDynamicMainLayer.Name != DynamicMainLayerElementName) { return; } if (elementDynamicMainLayer.Children.Count < 2) { return; } Canvas elementDynamicPlotLayerViewport = elementDynamicMainLayer.FindName(DynamicPlotLayerViewportElementName) as Canvas; if (null == elementDynamicPlotLayerViewport) { return; } this.DrawPanel(panel, (long)panel.Tag, panelNumber); } }
/// <summary> /// Looks the through adjacent panel for overlap. /// </summary> /// <param name="panel">The panel.</param> /// <param name="comparisonPanel">The comparison panel.</param> /// <param name="offset">The offset.</param> internal static void LookThroughAdjacentPanelForOverlap(PanelWrapper panel, PanelWrapper comparisonPanel, double offset) { // all we need to do is determine if the items on the edge of the panels overlap. // so, really we are talking about a datamarker synmbol wide on either edge. // the seamedelementcolelction gives us the elements that are plotted // outside the bounds of our panel. foreach (FrameworkElement element in panel.SeamedElementCollection) { double elementLeft = Canvas.GetLeft(element); double elementWidth = element.Width; Collision collision; foreach (FrameworkElement comparisonElement in comparisonPanel.SeamedElementCollection) { FrameworkElement elementLabel = GraphBase.GetDataPointLabel(element); FrameworkElement comparisonElementLabel = GraphBase.GetDataPointLabel(comparisonElement); if (null != elementLabel && null != comparisonElementLabel) { GraphPoint elementGraphPoint = elementLabel.DataContext as GraphPoint; GraphPoint comparisonElementGraphPoint = comparisonElementLabel.DataContext as GraphPoint; if (null != elementGraphPoint && null != comparisonElementGraphPoint && elementGraphPoint.DataContext != comparisonElementGraphPoint.DataContext) { double comparisonLeft = Canvas.GetLeft(comparisonElement) + offset; bool flag = false; if (elementLeft < comparisonLeft && (elementLeft + elementWidth) > comparisonLeft) { // the elements collide // the element is to the left of the comparison and overlaps. flag = true; } else if (elementLeft > comparisonLeft && elementLeft < (comparisonLeft + elementWidth)) { // the elements collide // the element is to the right of the comparison and overlaps. flag = true; } if (true == flag) { collision = new Collision(element, element, true); panel.CollisionCollection.Add(collision); GraphBase.SetDataPointOverlapProperty(element, true); GraphBase.SetDataPointOverlapProperty(elementLabel, true); elementLabel.Visibility = Visibility.Collapsed; GraphBase.SetDataPointOverlapProperty(comparisonElement, true); GraphBase.SetDataPointOverlapProperty(comparisonElementLabel, true); comparisonElementLabel.Visibility = Visibility.Collapsed; } } } } } }
/// <summary> /// Draws the graph. /// </summary> /// <param name="panel">The panel.</param> /// <param name="offset">The offset.</param> /// <param name="panelNumber">The panel number.</param> protected override void DrawPanel(PanelWrapper panel, long offset, int panelNumber) { if (null == this.VisibleWindow || !this.IsInitialized) { return; } this.CurrentWorkingPanelCallback = panelNumber; this.DynamicTopAxisLayer = ((Grid)panel.Children[0]).FindName(DynamicTopAxisLayerElementName) as Canvas; this.DynamicPlotLayerViewport = ((Grid)panel.Children[0]).FindName(DynamicPlotLayerViewportElementName) as Canvas; this.DynamicPlotLayerViewport.SizeChanged += new SizeChangedEventHandler(this.DynamicPlotLayerViewport_SizeChanged); this.DynamicPlotLayer = ((Grid)panel.Children[0]).FindName(DynamicPlotLayerElementName) as Canvas; this.DynamicTopAxisLayerViewport = ((Grid)panel.Children[0]).FindName(DynamicTopAxisLayerViewportElementName) as Canvas; this.MinimizedPlotLayer = ((Grid)panel.Children[0]).FindName(MinimizedPlotLayerElementName) as Canvas; this.DynamicPlotLayer.Visibility = this.Minimized ? Visibility.Collapsed : Visibility.Visible; if (this.MinimizedPlotLayer != null) { this.MinimizedPlotLayer.Visibility = this.Minimized ? Visibility.Visible : Visibility.Collapsed; } CollisionDetectionManager collisionDetectionManager = new CollisionDetectionManager(); GraphBase.SetCollisionDetectionManager(panel, collisionDetectionManager); GraphBase.SetCollisionDetectionManager(this.DynamicPlotLayer, collisionDetectionManager); // need to increment the currentWindowStartDate by figuring out the amount of time a // window/page represents, and times that by the number of pages we are from the start. // we do this by figuring out the ticks for a window. // we then multiply this by the number in the offset. long ticks = 0; long totalTicks = 0; try { if (null != this.VisibleWindow) { ticks = checked(this.VisibleWindow.Ticks * offset); totalTicks = checked(this.AxisStartDate.Ticks + ticks); } } catch (System.OverflowException e) { // style update. if (null != e) { totalTicks = DateTime.MaxValue.Ticks + 1; } } ////it is possible to configure the Graph so that we try to go to a date that is beyond that ////that can be represented. e.g Window size is 10 years, and goto some huge page offset. ////if we do try that, then do nothing. if (totalTicks <= DateTime.MaxValue.Ticks) { this.CurrentWindowStartDate = this.AxisStartDate.AddTicks(ticks); panel.StartDate = this.CurrentWindowStartDate; panel.EndDate = panel.StartDate.AddTicks(this.VisibleWindow.Ticks); this.DynamicPlotLayer.Children.Clear(); this.DynamicTopAxisLayer.Children.Clear(); // when we draw the graph, we want to plot first because the overlap // detection does not want to have grid lines to worry about. if (this.DataContext != null) { this.InvalidDateSelected = false; DateTime tempDate = this.CurrentWindowStartDate.AddTicks(this.VisibleWindow.Ticks); IEnumerable enumerable = this.GetFilteredData(this.CurrentWindowStartDate, tempDate); if (enumerable != null) { this.DrawFilteredTimeGraph(enumerable, panel); } else { this.DrawTimeGraph(); } } this.DrawTimeXAxis(offset); } }
/// <summary> /// Virtual. Plots a time graph with a filtered set of data. /// </summary> /// <param name="subSet">Filtered set of data.</param> /// <param name="panel">The panel.</param> protected virtual void DrawFilteredTimeGraph(System.Collections.IEnumerable subSet, PanelWrapper panel) { }
/// <summary> /// Draw into panel. /// </summary> /// <param name="panel">The panel.</param> /// <param name="offset">The offset.</param> /// <param name="panelNumber">The panel number.</param> protected virtual void DrawPanel(PanelWrapper panel, long offset, int panelNumber) { }
/// <summary> /// Adjusts the labels. /// </summary> /// <param name="panel">The panel.</param> private void AdjustLabels(PanelWrapper panel) { foreach (MedicationLabel label in panel.LabelElements) { GraphPoint gp = label.DataContext as GraphPoint; object actualData = gp.DataContext; if (!this.labelsLayerData.Contains(actualData)) { this.labelsOverlapping = false; this.labelsLayerData.Add(actualData); DateTime startDate = gp.X1; DateTime endDate = gp.X1; if (gp.X2.HasValue) { endDate = gp.X2.Value; } else { endDate = this.TitleEndDate > endDate ? this.TitleEndDate : endDate; } bool showInView = false; if (startDate >= this.TitleStartDate && startDate <= this.TitleEndDate) { showInView = true; } else if (endDate >= this.TitleStartDate && endDate <= this.TitleEndDate) { showInView = true; startDate = this.TitleStartDate; } else if (startDate < this.TitleStartDate && endDate >= this.TitleEndDate) { showInView = true; startDate = this.TitleStartDate; } if (showInView) { label.Mode = this.LabelMode; label.Visibility = this.ShowDataPointLabels; label.Margin = new Thickness(); label.ClearValue(FrameworkElement.WidthProperty); this.labelsLayer.Children.Add(label); double top; double left = this.GetXForDateInPanel(startDate, panel.StartDate) + Canvas.GetLeft(panel); left = Math.Max(0, left); double width = label.GetDesiredWidth(this.DynamicMainLayerViewport.ActualWidth - left); // label.DesiredSize.Width; label.Width = width; if (this.StackLabels) { top = this.GetLabelTop(left, width); Canvas.SetZIndex(label, this.labelZIndex); GraphBase.SetDataPointOverlapProperty(label, false); } else { top = this.GetLabelTop(0); double newLeft = this.GetLabelLeft(left, width, label); if (newLeft != left) { FrameworkElement previousLabel = this.GetLabelAtLeft(newLeft); if (previousLabel != null) { label.Width = previousLabel.Width; } label.GetDesiredWidth(this.DynamicMainLayerViewport.ActualWidth - newLeft); Canvas.SetZIndex(label, --this.labelZIndex); label.Margin = new Thickness(newLeft - left, this.labelOverlayOffset, label.Margin.Right, label.Margin.Bottom); GraphBase.SetDataPointOverlapProperty(label, true); } else { this.labelZIndex = Int16.MaxValue; Canvas.SetZIndex(label, this.labelZIndex); label.Margin = new Thickness(0, 0, label.Margin.Right, label.Margin.Bottom); GraphBase.SetDataPointOverlapProperty(label, false); } } if (!double.IsNaN(top)) { Canvas.SetLeft(label, (int)left); Canvas.SetTop(label, (int)top); } if (this.labelsOverlapping) { this.labelsLayer.Children.Remove(label); this.AddLabelOvercrowdingNotification(left); } } } } }
/// <summary> /// Plots the graph at specified offset. /// </summary> /// <param name="offset">Offset at which to plot the graph.</param> /// <returns>Returns the panel at the specified offset.</returns> protected PanelWrapper DrawGraph(long offset) { PanelWrapper panel = null; panel = new PanelWrapper(); panel.Height = this.DynamicMainLayerViewport.ActualHeight; panel.Width = this.DynamicMainLayerViewport.ActualWidth; this.DynamicMainLayer = this.DynamicMainLayerTemplate.LoadContent() as FrameworkElement; panel.Children.Add(this.DynamicMainLayer); this.DynamicMainLayerViewport.Children.Add(panel); panel.Tag = offset; return panel; }
/// <summary> /// Adds the label element. /// </summary> /// <param name="gp">GraphPoint containing the co-ordinates for the label.</param> /// <param name="panel">The panel to add the label element.</param> private void AddLabelElement(GraphPoint gp, PanelWrapper panel) { FrameworkElement labelElement = null; if (gp.Label == null) { if (null != this.LabelTemplate) { labelElement = this.LabelTemplate.LoadContent() as FrameworkElement; } } else { labelElement = gp.Label; } if (null != labelElement) { labelElement.DataContext = gp; TimeActivityGraph.SetIsLabel(labelElement, true); panel.LabelElements.Add(labelElement); labelElement.Visibility = this.ShowDataPointLabels; labelElement.MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(this.LabelElement_MouseLeftButtonDown); } }
/// <summary> /// Renders the activities. /// </summary> /// <param name="panel">The panel.</param> private void RenderActivities(PanelWrapper panel) { CollisionDetectionManager collisionManager = GraphBase.GetCollisionDetectionManager(this.DynamicPlotLayer); if (this.activities.Count > 0) { int activitiesCounter = this.activities.Count; foreach (IEnumerable<object> eventset in this.activities) { if (panel.AbortLayout) { break; } IEnumerable eventSubSet = GetFilteredActivityData(eventset, panel.StartDate, panel.EndDate); foreach (object o in eventSubSet) { if (panel.AbortLayout) { break; } GraphPoint gp = this.GetBoundGraphPoint(o); if (null == gp) { return; } gp.X1Pixel = (int)this.GetXForDateInPanel(gp.X1, panel.StartDate); gp.X2Pixel = (int)(gp.X2.HasValue ? this.GetXForDate(gp.X2.Value) : this.GetXForDate(this.AxisEndDate)); gp.Y1Pixel = this.NonDynamicRightAxisViewPort.ActualHeight - (activitiesCounter * this.ActivityRowHeight); bool addActivityToPanel = false; if (gp.X1Pixel >= 0 && gp.X1Pixel <= this.DynamicMainLayerViewport.ActualWidth) { addActivityToPanel = true; } else if (gp.X2.HasValue && gp.X2Pixel >= 0 && gp.X2Pixel <= this.DynamicMainLayerViewport.ActualWidth) { addActivityToPanel = true; } if (!addActivityToPanel) { continue; } FrameworkElement element = this.AddMarkerFromGraphPoint(gp, true); double left = gp.X1Pixel + GraphBase.GetXOffset(element); double right = left + element.Width; Canvas.SetLeft(element, left); Canvas.SetTop(element, gp.Y1Pixel + GraphBase.GetYOffset(element)); element.MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(this.Activity_MouseLeftButtonDown); if ((left < 0 && right > 0) || (left < this.DynamicMainLayerViewport.ActualWidth && right > this.DynamicMainLayerViewport.ActualWidth)) { this.CurrentWorkingPanel.SeamedElementCollection.Add(element); } if (this.DetectCollisions) { FrameworkElement clashElement = collisionManager.RegisterAndTestIfEventMarkerOverlaps(element); if (clashElement != null) { panel.CollisionCollection.Add(new Collision(clashElement, element, true)); } } } activitiesCounter--; if (this.DetectCollisions) { PanelWrapper otherPanel = null; // we get panel 2 then panel 1 when getting both panels. double markerOffsetToUse = 0; // perform seam detection // panel1 is to the left of panel2 if (this.CurrentWorkingPanel == this.Panel1) { // panel2 markers must be incremented by the width of the layer. otherPanel = this.Panel2; markerOffsetToUse = this.Panel1.Width; } else { // panel1 markers must be decremented by the width of the plot layer. // if we are renewing both panels, then do not do collisions detections on seams. if (true != this.RenewingBothPanels) { otherPanel = this.Panel1; markerOffsetToUse = this.Panel2.Width * -1; } } // this gets run if we are renewing a panel, but if renewing both, only for panel 1. if (null != otherPanel) { TimeActivityGraph.LookThroughAdjacentPanelForOverlap(this.CurrentWorkingPanel, otherPanel, markerOffsetToUse); } double lastCollisionPosition = -1; foreach (Collision collision in panel.CollisionCollection) { collision.ClusterStartElement.Visibility = Visibility.Collapsed; collision.ClusterEndElement.Visibility = Visibility.Collapsed; FrameworkElement flagStick = GetFlagStick(collision.ClusterStartElement); if (flagStick != null) { flagStick.Visibility = Visibility.Collapsed; } flagStick = GetFlagStick(collision.ClusterEndElement); if (flagStick != null) { flagStick.Visibility = Visibility.Collapsed; } if (null != this.CollisionTemplate) { FrameworkElement collisionIcon = this.CollisionTemplate.LoadContent() as FrameworkElement; if (null != collisionIcon) { double localxPosition = Canvas.GetLeft(collision.ClusterStartElement); double localyPosition = Canvas.GetTop(collision.ClusterStartElement); if (lastCollisionPosition == -1 || localxPosition > lastCollisionPosition + (1.5 * collisionIcon.Width)) { if (true == collision.ClusterShowingIcon) { lastCollisionPosition = localxPosition; Canvas.SetLeft(collisionIcon, lastCollisionPosition); Canvas.SetTop(collisionIcon, localyPosition); this.DynamicPlotLayer.Children.Add(collisionIcon); } } } } } } } } }
/// <summary> /// Looks the through adjacent panel for overlap. /// </summary> /// <param name="panel">The panel.</param> /// <param name="comparisonPanel">The comparison panel.</param> /// <param name="offset">The offset.</param> private static new void LookThroughAdjacentPanelForOverlap(PanelWrapper panel, PanelWrapper comparisonPanel, double offset) { // all we need to do is determine if the items on the edge of the panels overlap. // so, really we are talking about a datamarker symbol wide on either edge. // the seamedelementcolelction gives us the elements that are plotted // outside the bounds of our panel. foreach (FrameworkElement element in panel.SeamedElementCollection) { double elementLeft = Canvas.GetLeft(element); double elementWidth = element.Width; Collision collision; foreach (FrameworkElement comparisonElement in comparisonPanel.SeamedElementCollection) { GraphPoint elementDataContext = element.DataContext as GraphPoint; GraphPoint comparisionElementDataContext = comparisonElement.DataContext as GraphPoint; if (elementDataContext != null && comparisionElementDataContext != null) { bool areDataContextsSame = false; areDataContextsSame = elementDataContext.X1 == comparisionElementDataContext.X1; if (elementDataContext.X2.HasValue && comparisionElementDataContext.X2.HasValue) { areDataContextsSame = elementDataContext.X2.Value == comparisionElementDataContext.X2.Value; } else if ((elementDataContext.X2.HasValue && !comparisionElementDataContext.X2.HasValue) || (!elementDataContext.X2.HasValue && comparisionElementDataContext.X2.HasValue)) { areDataContextsSame = false; } if (null != element && null != comparisonElement && !areDataContextsSame) { double comparisonLeft = Canvas.GetLeft(comparisonElement) + offset; bool flag = false; if (elementLeft < comparisonLeft && (elementLeft + elementWidth) > comparisonLeft) { // the elements collide // the element is to the left of the comparison and overlaps. flag = true; } else if (elementLeft > comparisonLeft && elementLeft < (comparisonLeft + elementWidth)) { // the elements collide // the element is to the right of the comparison and overlaps. flag = true; } if (true == flag) { collision = new Collision(element, element, true); panel.CollisionCollection.Add(collision); } } } } } }
/// <summary> /// Virtual. Plots a time graph with a filtered set of data. /// </summary> /// <param name="subSet">Filtered set of data.</param> /// <param name="panel">The panel to plot the data.</param> protected override void DrawFilteredTimeGraph(System.Collections.IEnumerable subSet, PanelWrapper panel) { if (!panel.AbortLayout) { foreach (object o in subSet) { if (panel.AbortLayout) { break; } GraphPoint gp = this.GetBoundGraphPoint(o); if (null == gp) { return; } gp.X1Pixel = (int)this.GetXForDate(gp.X1); gp.X2Pixel = gp.X2.HasValue ? this.GetXForDate(gp.X2.Value) : this.GetXForDate(this.AxisEndDate); gp.Y1Pixel = this.interpolationLineStartYPosition; if (!this.Minimized) { FrameworkElement element = this.AddMarkerFromGraphPoint(gp, false); Canvas.SetLeft(element, gp.X1Pixel > 0 ? gp.X1Pixel : 0); Canvas.SetTop(element, gp.Y1Pixel); Canvas.SetZIndex(element, 10); element.MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(this.InterpolationLine_MouseLeftButtonDown); this.AddLabelElement(gp, panel); } else { if ((gp.X1Pixel > 0 || gp.X2Pixel > 0) && gp.X1Pixel < this.DynamicMainLayerViewport.ActualWidth) { this.MinimizedPlotLayer.Children.Add(this.GetInterpolationLine(gp)); } } } if (!this.Minimized && this.ShowActivities) { this.RenderActivities(panel); } } }
/// <summary> /// Virtual. Plots a time graph with a filtered set of data. /// </summary> /// <param name="subSet">Filtered set of data.</param> /// <param name="panel">The panel.</param> protected override void DrawFilteredTimeGraph(IEnumerable subSet, PanelWrapper panel) { base.DrawFilteredTimeGraph(subSet, panel); // Maintain the previous and current point plotted for the virtual method call GraphPoint prevPoint = new GraphPoint(); GraphPoint currPoint = new GraphPoint(); System.Collections.Generic.Stack<FrameworkElement> dataPointStack = new System.Collections.Generic.Stack<FrameworkElement>(); System.Collections.Generic.Stack<FrameworkElement> dataPointLabelStack = new System.Collections.Generic.Stack<FrameworkElement>(); CollisionDetectionManager collisionManager = GraphBase.GetCollisionDetectionManager(this.DynamicPlotLayer); foreach (object o in subSet) { if (panel.AbortLayout) { break; } GraphPoint gp = this.GetBoundGraphPoint(o); if (null == gp) { return; } gp.X1Pixel = this.GetXForDate(gp.X1); gp.Y1Pixel = this.GetYForValue(gp.Y1); if (!Double.IsNaN(gp.Y2)) { gp.Y2Pixel = this.GetYForValue(gp.Y2); } currPoint = gp; // process the plotted data marker this.ProcessPlottedDataMarker(prevPoint, currPoint); if (!this.Minimized) { if (!double.IsNaN(gp.Y1) && currPoint.X1Pixel >= 0 && currPoint.X1Pixel < this.DynamicMainLayerViewport.ActualWidth) { FrameworkElement marker = this.GetPlottedDataMarker(gp); double left = Canvas.GetLeft(marker); #if !SILVERLIGHT // For WPF should snap to grid if requested bool snap = GraphBase.GetSnapToPixels(marker); if (marker.SnapsToDevicePixels != snap) { marker.SnapsToDevicePixels = snap; } #endif if (left < 0 || (left + marker.Width) > this.DynamicMainLayerViewport.ActualWidth) { this.CurrentWorkingPanel.SeamedElementCollection.Add(marker); } this.DynamicPlotLayer.Children.Add(marker); dataPointStack.Push(marker); FrameworkElement labelElement = null; if (null != this.LabelTemplate) { labelElement = this.LabelTemplate.LoadContent() as FrameworkElement; labelElement.DataContext = gp; dataPointLabelStack.Push(labelElement); } if (null != labelElement) { double offsetValueX = GraphBase.GetXOffset(labelElement); double offsetValueY = GraphBase.GetYOffset(labelElement); // define the label position double labelY = currPoint.Y1Pixel; if (!double.IsNaN(gp.Y2) && gp.Y1 < gp.Y2) { labelY = currPoint.Y2Pixel; } double markerOffset = Math.Abs(GraphBase.GetYOffset(marker)) + 2; Canvas.SetTop(labelElement, (labelY - markerOffset) + offsetValueY); Canvas.SetLeft(labelElement, currPoint.X1Pixel + offsetValueX); labelElement.Visibility = this.ShowDataPointLabels; this.DynamicPlotLayer.Children.Add(labelElement); GraphBase.SetDataPointLabel(marker, labelElement); panel.LabelElements.Add(labelElement); marker.MouseEnter += new MouseEventHandler(this.DataPointMarker_MouseEnter); marker.MouseLeave += new MouseEventHandler(this.DataPointMarker_MouseLeave); } } } prevPoint = currPoint; } if (!panel.AbortLayout && this.DetectCollisions) { Collision previousCollision = null; // get the last items in the collection for the data context object[] lastItems = this.GetLastDataPoints(); object lastObject = lastItems[1]; object secondLastObject = lastItems[0]; byte lastItemsCheck = 0; while (dataPointStack.Count > 0) { FrameworkElement ele = dataPointStack.Pop(); FrameworkElement labelEle = GraphBase.GetDataPointLabel(ele); if (lastItemsCheck < 2 && null != labelEle && null != labelEle.DataContext) { // this is the last item on the page. // we plot back to front to check if things overlap. ++lastItemsCheck; object gp = ((GraphPoint)labelEle.DataContext).DataContext; if (lastObject == gp) { // this is the last item in the series. GraphBase.SetLastItem(ele, true); labelEle.Visibility = Visibility.Visible; labelEle.RenderTransform = this.LabelTransform; } if (secondLastObject == gp) { // this is the second last item in the series. GraphBase.SetSecondToLast(ele, true); labelEle.Visibility = Visibility.Visible; } } FrameworkElement clashElement = collisionManager.RegisterAndTestIfMarkerOverlaps(ele); if (null != clashElement) { previousCollision = new Collision(clashElement, ele, true); this.CurrentWorkingPanel.CollisionCollection.Add(previousCollision); GraphBase.SetDataPointOverlapProperty(ele, true); GraphBase.SetDataPointOverlapProperty(labelEle, true); labelEle.Visibility = Visibility.Collapsed; GraphBase.SetDataPointOverlapProperty(clashElement, true); FrameworkElement clashElementLabel = GraphBase.GetDataPointLabel(clashElement); GraphBase.SetDataPointOverlapProperty(clashElementLabel, true); clashElementLabel.Visibility = Visibility.Collapsed; } else { // this marker does not overlap previousCollision = null; } } while (dataPointLabelStack.Count > 0) { FrameworkElement ele2 = dataPointLabelStack.Pop(); if (collisionManager.RegisterAndTestIfLabelOverlaps(ele2)) { GraphBase.SetDataPointOverlapProperty(ele2, true); ele2.Visibility = Visibility.Collapsed; } } PanelWrapper otherPanel = null; // we get panel 2 then panel 1 when getting both panels. double markerOffsetToUse = 0; // perform seam detection // panel1 is to the left of panel2 if (this.CurrentWorkingPanel == this.Panel1) { // panel2 markers must be incremented by the width of the layer. otherPanel = this.Panel2; markerOffsetToUse = this.Panel1.Width; } else { // panel1 markers must be decremented by the width of the plot layer. // if we are renewing both panels, then do not do collisions detections on seams for if (true != this.RenewingBothPanels) { otherPanel = this.Panel1; markerOffsetToUse = this.Panel2.Width * -1; } } // this gets run if we are renewing a panel, but if renewing both, only for panel 1 if (null != otherPanel) { LookThroughAdjacentPanelForOverlap(this.CurrentWorkingPanel, otherPanel, markerOffsetToUse); } double lastCollisionPosition = -1; foreach (Collision collision in this.CurrentWorkingPanel.CollisionCollection) { if (null != this.CollisionTemplate) { FrameworkElement collisionIcon = this.CollisionTemplate.LoadContent() as FrameworkElement; double theXOffset = GraphBase.GetXOffset(collisionIcon); double theYOffset = GraphBase.GetYOffset(collisionIcon); if (null != collisionIcon) { double localxPosition = Canvas.GetLeft(collision.ClusterStartElement) + theXOffset; double localyPosition = Canvas.GetTop(collision.ClusterStartElement) + theYOffset; if (lastCollisionPosition == -1 || localxPosition < lastCollisionPosition - 46) { lastCollisionPosition = localxPosition; Canvas.SetLeft(collisionIcon, localxPosition); Canvas.SetTop(collisionIcon, localyPosition); if (true == collision.ClusterShowingIcon) { this.DynamicPlotLayer.Children.Add(collisionIcon); } } } } } } }