コード例 #1
0
ファイル: TimeActivityGraph.cs プロジェクト: rbirkby/mscui
        /// <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);
                            }
                        }
                    }
                }
            }
        }
コード例 #2
0
ファイル: TimeGraphBase.cs プロジェクト: rbirkby/mscui
        /// <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;
                            }
                        }
                    }
                }
            }
        }
コード例 #3
0
ファイル: TimeAndYGraphBase.cs プロジェクト: rbirkby/mscui
        /// <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);
                                }
                            }
                        }
                    }
                }
            }
        }