Example #1
0
        /// <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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
        /// <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);
            }
        }
Example #4
0
        /// <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;
                            }
                        }
                    }
                }
            }
        }
Example #5
0
        /// <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);
            }            
        }
Example #6
0
 /// <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)
 {
 }
Example #7
0
 /// <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)
 {
 }
Example #8
0
        /// <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);
                        }
                    }
                }
            }
        }
Example #9
0
        /// <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;
        }
Example #10
0
        /// <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);                
            }
        }
Example #11
0
        /// <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);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Example #12
0
        /// <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);
                            }
                        }
                    }
                }
            }
        }
Example #13
0
        /// <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);
                }
            }
        }
Example #14
0
        /// <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);
                                }
                            }
                        }
                    }
                }
            }
        }