예제 #1
0
        private double staticAxisMargin = 1;         // px

        private void CreateCommonLabels(double[] screenTicksX)
        {
            Size renderSize = RenderSize;

            commonLabelsCanvas.Children.Clear();
            UIElement[] labels = this.labels.ToArray();

            double minCoordUnsorted = ToScreen(range.Min);
            double maxCoordUnsorted = ToScreen(range.Max);

            double minCoord = Math.Min(minCoordUnsorted, maxCoordUnsorted);
            double maxCoord = Math.Max(minCoordUnsorted, maxCoordUnsorted);

            double maxCoordDiff = (maxCoord - minCoord) / labels.Length / 2.0;

            double minCoordToAdd = minCoord - maxCoordDiff;
            double maxCoordToAdd = maxCoord + maxCoordDiff;

            for (int i = 0; i < ticks.Length; i++)
            {
                UIElement tickLabel = labels[i];
                if (tickLabel == null)
                {
                    continue;
                }

                // getting real size of label
                tickLabel.Measure(renderSize);
                Size tickLabelSize = tickLabel.DesiredSize;

                double screenX = screenTicksX[i];
                double coord   = screenX - getSize(tickLabelSize) / 2;

                if (isStaticAxis)
                {
                    if (Math.Abs(screenX - minCoord) < maxCoordDiff)
                    {
                        coord = screenX + staticAxisMargin;
                    }
                    else if (Math.Abs(screenX - maxCoord) < maxCoordDiff)
                    {
                        coord = screenX - getSize(tickLabelSize) - staticAxisMargin;
                    }
                }

                if (coord < minCoordToAdd || coord > maxCoordToAdd)
                {
                    continue;
                }

                if (coord.IsNaN())
                {
                    continue;
                }

                StackCanvas.SetCoordinate(tickLabel, coord);

                commonLabelsCanvas.Children.Add(tickLabel);
            }
        }
예제 #2
0
        private void DoDrawMayorLabels()
        {
            additionalLabelsCanvas.Children.Clear();
            ITicksProvider <T> mayorTicksProvider = ticksProvider.MayorProvider;

            if (mayorTicksProvider != null && MayorLabelProvider != null)
            {
                Size renderSize = RenderSize;
                var  mayorTicks = mayorTicksProvider.GetTicks(range, DefaultTicksProvider.DefaultTicksCount);

                double[] screenCoords = mayorTicks.Ticks.Select(tick => createDataPoint(convertToDouble(tick))).
                                        Select(p => p.DataToScreen(transform)).Select(p => getCoordinate(p)).ToArray();

                // todo this is not the best decision - when displaying, for example,
                // milliseconds, it causes to create hundreds and thousands of textBlocks.
                double rangesRatio = GetRangesRatio(mayorTicks.Ticks.GetPairs().ToArray()[0], range);

                object          info    = mayorTicks.Info;
                MayorLabelsInfo newInfo = new MayorLabelsInfo
                {
                    Info             = info,
                    MayorLabelsCount = (int)Math.Ceiling(rangesRatio)
                };

                var newMayorTicks = new TicksInfo <T>
                {
                    Info      = newInfo,
                    Ticks     = mayorTicks.Ticks,
                    TickSizes = mayorTicks.TickSizes
                };

                UIElement[] additionalLabels = MayorLabelProvider.CreateLabels(newMayorTicks);

                for (int i = 0; i < additionalLabels.Length; i++)
                {
                    if (screenCoords[i].IsNaN())
                    {
                        continue;
                    }

                    UIElement tickLabel = additionalLabels[i];

                    tickLabel.Measure(renderSize);

                    StackCanvas.SetCoordinate(tickLabel, screenCoords[i]);
                    StackCanvas.SetEndCoordinate(tickLabel, screenCoords[i + 1]);

                    if (tickLabel is FrameworkElement)
                    {
                        ((FrameworkElement)tickLabel).LayoutTransform = additionalLabelTransform;
                    }

                    additionalLabelsCanvas.Children.Add(tickLabel);
                }
            }
        }
예제 #3
0
        private static void OnCoordinateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UIElement reference = d as UIElement;

            if (reference != null)
            {
                StackCanvas parent = VisualTreeHelper.GetParent(reference) as StackCanvas;
                if (parent != null)
                {
                    parent.InvalidateArrange();
                }
            }
        }
예제 #4
0
        private void DoDrawMayorLabels()
        {
            AdditionalLabelsCanvas.Children.Clear();
            ITicksProvider <T> mayorTicksProvider = ticksProvider.MayorProvider;

            if (mayorTicksProvider != null && MayorLabelProvider != null)
            {
                Size renderSize = RenderSize;
                //if (renderSize.Width == 0 || renderSize.Height == 0) return;
                var mayorTicks = mayorTicksProvider.GetTicks(range, DefaultTicksProvider.DefaultTicksCount);

                double[] screenCoords = mayorTicks.Ticks.Select(tick => createDataPoint(convertToDouble(tick))).
                                        Select(p => p.DataToScreen(transform)).Select(p => getCoordinate(p)).ToArray();

                int expectedMayorLabelsCount = mayorTicks.Ticks.Length;
                // todo this is not the best decision - when displaying, for example,
                // milliseconds, it causes to create hundreds and thousands of textBlocks.
                double rangesRatio = GetRangesRatio(mayorTicks.Ticks.GetPairs().ToArray()[0], range);

                object          info    = mayorTicks.Info;
                MayorLabelsInfo newInfo = new MayorLabelsInfo
                {
                    Info             = info,
                    MayorLabelsCount = (int)Math.Ceiling(rangesRatio)
                };

                var newMayorTicks = new TicksInfo <T>
                {
                    Info      = newInfo,
                    Ticks     = mayorTicks.Ticks,
                    TickSizes = mayorTicks.TickSizes
                };

                IEnumerable <FrameworkElement> additionalLabels = MayorLabelProvider.CreateLabels(newMayorTicks);

                int i = 0;
                foreach (FrameworkElement fe in additionalLabels)
                {
                    fe.Measure(renderSize);

                    StackCanvas.SetCoordinate(fe, screenCoords[i]);
                    if (i + 1 < screenCoords.Length)
                    {
                        StackCanvas.SetEndCoordinate(fe, screenCoords[i + 1]);
                    }

                    AdditionalLabelsCanvas.Children.Add(fe);
                    i++;
                }
            }
        }
예제 #5
0
        /*protected override void OnRender(DrawingContext dc)
         * {
         *  base.OnRender(dc);
         *
         *  if (!rendered)
         *  {
         *      UpdateUIRepresentation();
         *  }
         *  rendered = true;
         * }*/

        private void InitializeComponent()
        {
            LayoutRoot              = new Grid();
            LayoutRoot.Background   = new SolidColorBrush(Colors.White);
            TicksPath               = new Path();
            TicksPath.Stroke        = new SolidColorBrush(Colors.Black);
            CommonLabelsCanvas      = new StackCanvas();
            AdditionalLabelsCanvas  = new StackCanvas();
            AdditionalAxisTranslate = new TranslateTransform();
            LayoutRoot.Children.Add(TicksPath);
            LayoutRoot.Children.Add(CommonLabelsCanvas);
            LayoutRoot.Children.Add(AdditionalLabelsCanvas);
            this.Content = LayoutRoot;
        }
예제 #6
0
        private void CreateCommonLabels(double[] screenTicksX)
        {
            Size renderSize = RenderSize;

            CommonLabelsCanvas.Children.Clear();
            List <FrameworkElement> .Enumerator labelsEnumerator = labels.GetEnumerator();
            //IEnumerator<UIElement> canvasEnumerator= CommonLabelsCanvas.Children.GetEnumerator();

            for (int i = 0; i < labels.Count; i++)
            {
                FrameworkElement tickLabel = labels[i];

                Size tickLabelSize = new Size(tickLabel.ActualWidth, tickLabel.ActualHeight);

                StackCanvas.SetCoordinate(tickLabel, screenTicksX[i] - getSize(tickLabelSize) / 2);


                CommonLabelsCanvas.Children.Add(tickLabel);
            }
        }
예제 #7
0
        private void CreateCommonLabels(double[] screenTicksX)
        {
            Size renderSize = RenderSize;

            CommonLabelsCanvas.Children.Clear();
            List <FrameworkElement> .Enumerator labelsEnumerator = labels.GetEnumerator();
            //IEnumerator<UIElement> canvasEnumerator= CommonLabelsCanvas.Children.GetEnumerator();

            for (int i = 0; i < labels.Count; i++)
            {
                FrameworkElement tickLabel = labels[i];

                Size tickLabelSize = new Size(tickLabel.ActualWidth, tickLabel.ActualHeight);

                StackCanvas.SetCoordinate(tickLabel, screenTicksX[i] - getSize(tickLabelSize) / 2);


                CommonLabelsCanvas.Children.Add(tickLabel);
                //if (i >= allocatedLabels)
                //{
                //    CommonLabelsCanvas.Children.Add(tickLabel);
                //}
                //else
                //{
                //    labelsEnumerator.MoveNext();
                //    i = CommonLabelsCanvas.Children.IndexOf(labelsEnumerator.Current);
                //    //labelsEnumerator.Current = tickLabel;
                //    //CommonLabelsCanvas.Children.
                //    CommonLabelsCanvas.Children[i] = tickLabel;

                //}
            }
            //for (int j = allocatedLabels-1; j >= ticks.Length; j--) {
            //    CommonLabelsCanvas.Children.RemoveAt(j);
            //}
            //allocatedLabels = CommonLabelsCanvas.Children.Count;
        }
예제 #8
0
        private double staticAxisMargin = 1; // px

        private void DoDrawCommonLabels(double[] screenTicksX)
        {
            Size renderSize = RenderSize;

            commonLabelsCanvas.Children.Clear();

#if DEBUG
            if (labels != null)
            {
                foreach (FrameworkElement item in labels)
                {
                    if (item != null)
                    {
                        Debug.Assert(item.Parent == null);
                    }
                }
            }
#endif

            double minCoordUnsorted = ToScreen(range.Min);
            double maxCoordUnsorted = ToScreen(range.Max);

            double minCoord = Math.Min(minCoordUnsorted, maxCoordUnsorted);
            double maxCoord = Math.Max(minCoordUnsorted, maxCoordUnsorted);

            double maxCoordDiff = (maxCoord - minCoord) / labels.Length / 2.0;

            double minCoordToAdd = minCoord - maxCoordDiff;
            double maxCoordToAdd = maxCoord + maxCoordDiff;

            for (int i = 0; i < ticks.Length; i++)
            {
                FrameworkElement tickLabel = (FrameworkElement)labels[i];
                if (tickLabel == null)
                {
                    continue;
                }

                Debug.Assert(((FrameworkElement)tickLabel).Parent == null);

                tickLabel.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));

                double screenX = screenTicksX[i];
                double coord   = screenX;

                tickLabel.HorizontalAlignment = HorizontalAlignment.Center;
                tickLabel.VerticalAlignment   = VerticalAlignment.Center;

                if (isStaticAxis)
                {
                    // getting real size of label
                    tickLabel.Measure(renderSize);
                    Size tickLabelSize = tickLabel.DesiredSize;

                    if (Math.Abs(screenX - minCoord) < maxCoordDiff)
                    {
                        coord = minCoord + staticAxisMargin;
                        if (placement.IsBottomOrTop())
                        {
                            tickLabel.HorizontalAlignment = HorizontalAlignment.Left;
                        }
                        else
                        {
                            tickLabel.VerticalAlignment = VerticalAlignment.Top;
                        }
                    }
                    else if (Math.Abs(screenX - maxCoord) < maxCoordDiff)
                    {
                        coord = maxCoord - getSize(tickLabelSize) / 2 - staticAxisMargin;
                        if (!placement.IsBottomOrTop())
                        {
                            tickLabel.VerticalAlignment = VerticalAlignment.Bottom;
                            coord = maxCoord - staticAxisMargin;
                        }
                    }
                }

                // label is out of visible area
                if (coord < minCoord || coord > maxCoord)
                {
                    continue;
                }

                if (coord.IsNaN())
                {
                    continue;
                }

                StackCanvas.SetCoordinate(tickLabel, coord);

                commonLabelsCanvas.Children.Add(tickLabel);
            }
        }
예제 #9
0
        private double staticAxisMargin = 1;         // px

        private void DrawCommonLabels(double[] screenTicksX)
        {
            Size renderSize = RenderSize;

            commonLabelsCanvas.Children.Clear();

#if DEBUG
            if (labels != null)
            {
                foreach (FrameworkElement item in labels)
                {
                    Debug.Assert(item.Parent == null);
                }
            }
#endif

            double minCoordUnsorted = ToScreen(range.Min);
            double maxCoordUnsorted = ToScreen(range.Max);

            double minCoord = Math.Min(minCoordUnsorted, maxCoordUnsorted);
            double maxCoord = Math.Max(minCoordUnsorted, maxCoordUnsorted);

            double maxCoordDiff = (maxCoord - minCoord) / labels.Length / 2.0;

            double minCoordToAdd = minCoord - maxCoordDiff;
            double maxCoordToAdd = maxCoord + maxCoordDiff;

            for (int i = 0; i < ticks.Length; i++)
            {
                UIElement tickLabel = labels[i];

                Debug.Assert(((FrameworkElement)tickLabel).Parent == null);

                if (tickLabel == null)
                {
                    continue;
                }

                // getting real size of label
                tickLabel.Measure(renderSize);
                Size tickLabelSize = tickLabel.DesiredSize;

                double screenX = screenTicksX[i];
                double coord   = screenX;

                if (isStaticAxis)
                {
                    if (Math.Abs(screenX - minCoord) < maxCoordDiff)
                    {
                        coord = screenX + staticAxisMargin;
                    }
                    else if (Math.Abs(screenX - maxCoord) < maxCoordDiff)
                    {
                        coord = screenX - getSize(tickLabelSize) - staticAxisMargin;
                    }
                }

                if (coord < minCoordToAdd || coord > maxCoordToAdd)
                {
                    continue;
                }

                if (coord.IsNaN())
                {
                    continue;
                }

                StackCanvas.SetCoordinate(tickLabel, coord);

                commonLabelsCanvas.Children.Add(tickLabel);
            }
        }
예제 #10
0
        internal void UpdateUI()
        {
            if (range.IsEmpty)
            {
                return;
            }

            if (transform == null)
            {
                return;
            }

            if (independent)
            {
                InitTransform(RenderSize);
            }

            bool isHorizontal = Placement == AxisPlacement.Bottom || Placement == AxisPlacement.Top;

            if (transform.ScreenRect.Width == 0 && isHorizontal ||
                transform.ScreenRect.Height == 0 && !isHorizontal)
            {
                return;
            }

            if (!IsMeasureValid)
            {
                InvalidateMeasure();
            }

            Range <double> currentDoubleRange = new Range <double>(convertToDouble(range.Min), convertToDouble(range.Max));
            bool           sameLength         = Math.Abs(cachedPartLength - currentDoubleRange.GetLength()) / cachedPartLength < 0.01 || cachedPartLength == 0;

            if (UseSmoothPanning && sameLength)
            {
                Debug.WriteLine(Placement + " " + range + " " + axisLongRange);
                // current range is included into axisLongRange
                if (currentDoubleRange < axisLongRange)
                {
                    var    axisContent = (FrameworkElement)mainGrid.Children[0];
                    double leftScreen;
                    if (placement.IsBottomOrTop())
                    {
                        leftScreen = ((axisLongRange.Min - currentDoubleRange.Min) / currentDoubleRange.GetLength() + 1) * getSize(transform.ScreenRect.Size);
                    }
                    else
                    {
                        leftScreen = -((axisLongRange.Min - currentDoubleRange.Min) / currentDoubleRange.GetLength() + 1) * getSize(transform.ScreenRect.Size);
                    }

                    StackCanvas.SetCoordinate(axisContent, leftScreen);

                    // this call should be commented
                    // double rightScreen = ((axisLongRange.Max - currentDoubleRange.Max) / currentDoubleRange.GetLength() + 1) * getSize(transform.ScreenRect.Size);
                    // StackCanvas.SetEndCoordinate(axisContent, rightScreen);
                }
                else
                {
                    double length = currentDoubleRange.GetLength();
                    cachedPartLength = length;

                    // cached axis part is three times longer
                    double    min        = currentDoubleRange.Min - length;
                    double    max        = currentDoubleRange.Max + length;
                    Range <T> widerRange = new Range <T>(convertFromDouble(min), convertFromDouble(max));
                    axisLongRange = new Range <double>(min, max);

                    // rebuild entire ticks
                    FillParts(widerRange);

                    Debug.WriteLine("не шире " + Placement + " " + widerRange);

                    originalScreenTicks = screenTicks.ToArray();
                }

                // updating screen ticks (for axis grid)
                // 3 is a ratio of cached area to visible area
                double shift = (currentDoubleRange.Min - (axisLongRange.Min + axisLongRange.GetLength() / 3)) * getSize(transform.ScreenRect.Size);

                if (!placement.IsBottomOrTop())
                {
                    shift *= -1;
                }

                screenTicks = originalScreenTicks.ToArray();
                for (int i = 0; i < originalScreenTicks.Length; i++)
                {
                    screenTicks[i] -= shift;
                }
            }
            else
            {
                FillParts(range);
            }

            ScreenTicksChanged.Raise(this);
        }