private void CreateTicks()
        {
            TickChange result = TickChange.OK;
            TickChange prevResult;

            int prevActualTickCount = -1;

            int tickCount = DefaultTicksProvider.DefaultTicksCount;
            int iteration = 0;

            do
            {
                Verify.IsTrue(++iteration < maxTickArrangeIterations);

                ticksInfo = ticksProvider.GetTicks(range, tickCount);
                ticks     = ticksInfo.Ticks;

                if (ticks.Length == prevActualTickCount)
                {
                    result = TickChange.OK;
                    break;
                }

                prevActualTickCount = ticks.Length;

                labels = labelProvider.CreateLabels(ticksInfo);

                prevResult = result;
                result     = CheckLabelsArrangement(labels, ticks);

                if (prevResult == TickChange.Decrease && result == TickChange.Increase)
                {
                    // stop tick number oscillating
                    result = TickChange.OK;
                }

                if (result != TickChange.OK)
                {
                    int prevTickCount = tickCount;
                    if (result == TickChange.Decrease)
                    {
                        tickCount = ticksProvider.DecreaseTickCount(tickCount);
                    }
                    else
                    {
                        tickCount = ticksProvider.IncreaseTickCount(tickCount);
                        DebugVerify.Is(tickCount >= prevTickCount);
                    }

                    // ticks provider cannot create less ticks or tick number didn't change
                    if (tickCount == 0 || prevTickCount == tickCount)
                    {
                        tickCount = prevTickCount;
                        result    = TickChange.OK;
                    }
                }
            } while (result != TickChange.OK);
        }
        private TickChange CheckMinorTicksArrangement(ITicksInfo <T> minorTicks)
        {
            Size       renderSize = RenderSize;
            TickChange result     = TickChange.OK;

            if (minorTicks.Ticks.Length * 3 > getSize(renderSize))
            {
                result = TickChange.Decrease;
            }
            else if (minorTicks.Ticks.Length * 6 < getSize(renderSize))
            {
                result = TickChange.Increase;
            }
            return(result);
        }
        private TickChange CheckLabelsArrangement(IEnumerable <FrameworkElement> labels, T[] ticks)
        {
            var actualLabels = labels.Select((label, i) => new { Label = label, Index = i })
                               .Where(el => el.Label != null)
                               .Select(el => new { Label = el.Label, Tick = ticks[el.Index] })
                               .ToList();

            actualLabels.ForEach(item => item.Label.Measure(RenderSize));

            var sizeInfos = actualLabels.Select(item =>
                                                new { X = GetCoordinateFromTick(item.Tick), Size = getSize(item.Label.DesiredSize) })
                            .OrderBy(item => item.X).ToArray();

            TickChange res = TickChange.OK;

            int increaseCount = 0;

            for (int i = 0; i < sizeInfos.Length - 1; i++)
            {
                if ((sizeInfos[i].X + sizeInfos[i].Size * decreaseRatio) > sizeInfos[i + 1].X)
                {
                    res = TickChange.Decrease;
                    break;
                }
                if ((sizeInfos[i].X + sizeInfos[i].Size * increaseRatio) < sizeInfos[i + 1].X)
                {
                    increaseCount++;
                }
            }
            if (increaseCount > sizeInfos.Length / 2)
            {
                res = TickChange.Increase;
            }

            return(res);
        }
Exemple #4
0
        private TickChange CheckLabelsArrangement(Size axisSize, IEnumerable <FrameworkElement> inputLabels, double[] inputTicks)
        {
            var actualLabels1 = inputLabels.Select((label, i) => new { Label = label, Index = i });
            var actualLabels2 = actualLabels1.Where(el => el.Label != null);
            var actualLabels3 = actualLabels2.Select(el => new { Label = el.Label, Tick = inputTicks[el.Index] });
            var actualLabels  = actualLabels3.ToList();

            actualLabels.ForEach(item => item.Label.Measure(axisSize));

            var sizeInfos = actualLabels.Select(item =>
                                                new { Offset = GetCoordinateFromTick(item.Tick, axisSize), Size = IsHorizontal ? item.Label.DesiredSize.Width : item.Label.DesiredSize.Height })
                            .OrderBy(item => item.Offset).ToArray();

            // If distance between labels if smaller than threshold for any of the labels - decrease
            for (int i = 0; i < sizeInfos.Length - 1; i++)
            {
                if ((sizeInfos[i].Offset + sizeInfos[i].Size * decreaseRatio / 2) > sizeInfos[i + 1].Offset)
                {
                    return(TickChange.Decrease);
                }
            }

            // If distance between labels if larger than threshold for all of the labels - increase
            TickChange res = TickChange.Increase;

            for (int i = 0; i < sizeInfos.Length - 1; i++)
            {
                if ((sizeInfos[i].Offset + sizeInfos[i].Size * increaseRatio / 2) > sizeInfos[i + 1].Offset)
                {
                    res = TickChange.OK;
                    break;
                }
            }

            return(res);
        }
        private TickChange CheckLabelsArrangement(IEnumerable <FrameworkElement> labels, T[] ticks)
        {
            var actualLabels4 = labels.Select((label, i) => new { Label = label, Index = i });
            var actualLabels2 = actualLabels4.Where(el => el.Label != null);
            var actualLabels3 = actualLabels2.Select(el => new { Label = el.Label, Tick = ticks[el.Index] });
            var actualLabels  = actualLabels3.ToList();

            actualLabels.ForEach(item => item.Label.Measure(RenderSize));

            var sizeInfos = actualLabels.Select(item =>
                                                new { Offset = GetCoordinateFromTick(item.Tick), Size = getSize(new Size(item.Label.ActualWidth, item.Label.ActualHeight)) })
                            .OrderBy(item => item.Offset).ToArray();

            TickChange res = TickChange.OK;

            int increaseCount = 0;

            for (int i = 0; i < sizeInfos.Length - 1; i++)
            {
                if ((sizeInfos[i].Offset + sizeInfos[i].Size * decreaseRatio) > sizeInfos[i + 1].Offset)
                {
                    res = TickChange.Decrease;
                    break;
                }
                if ((sizeInfos[i].Offset + sizeInfos[i].Size * increaseRatio) < sizeInfos[i + 1].Offset)
                {
                    res = TickChange.Increase;
                    break;
                    //increaseCount++;
                }
            }
            //if (increaseCount > sizeInfos.Length / 2)
            //   res = TickChange.Increase;

            return(res);
        }
        private void DoDrawMinorTicks(GeometryGroup geomGroup)
        {
            ITicksProvider <T> minorTicksProvider = ticksProvider.MinorProvider;

            if (minorTicksProvider != null)
            {
                int            minorTicksCount      = DefaultTicksProvider.DefaultTicksCount;
                int            prevActualTicksCount = -1;
                ITicksInfo <T> minorTicks;
                TickChange     result = TickChange.OK;
                TickChange     prevResult;
                int            iteration = 0;
                //PerformanceCounter.startStopwatch("Minor ticks: computing tickCounts");
                do
                {
                    Verify.IsTrue(++iteration < maxTickArrangeIterations);

                    minorTicks = minorTicksProvider.GetTicks(range, minorTicksCount);

                    prevActualTicksCount = minorTicks.Ticks.Length;
                    prevResult           = result;
                    result = CheckMinorTicksArrangement(minorTicks);
                    if (prevResult == TickChange.Decrease && result == TickChange.Increase)
                    {
                        // stop tick number oscillating
                        result = TickChange.OK;
                    }
                    if (result == TickChange.Decrease)
                    {
                        int newMinorTicksCount = minorTicksProvider.DecreaseTickCount(minorTicksCount);
                        if (newMinorTicksCount == minorTicksCount)
                        {
                            result = TickChange.OK;
                        }
                        minorTicksCount = newMinorTicksCount;
                    }
                    else if (result == TickChange.Increase)
                    {
                        int newCount = minorTicksProvider.IncreaseTickCount(minorTicksCount);
                        if (newCount == minorTicksCount)
                        {
                            result = TickChange.OK;
                        }
                        minorTicksCount = newCount;
                    }
                } while (result != TickChange.OK);
                //PerformanceCounter.stopStopwatch("Minor ticks: computing tickCounts");

                minorTicks = minorTicksProvider.GetTicks(range, minorTicksCount);


                double[] sizes = minorTicks.TickSizes;

                double[] screenCoords = minorTicks.Ticks.Select(
                    coord => getCoordinate(createDataPoint(convertToDouble(coord)).
                                           ToScreen(converter))).ToArray();

                minorScreenTicks = new MinorTickInfo <double> [screenCoords.Length];
                for (int i = 0; i < screenCoords.Length; i++)
                {
                    minorScreenTicks[i] = new MinorTickInfo <double>(sizes[i], screenCoords[i]);
                }

                for (int i = 0; i < screenCoords.Length; i++)
                {
                    double screenCoord = screenCoords[i];
                    if (i + usedTicks < allocatedTicks)
                    {
                        //PerformanceCounter.startStopwatch("Minor ticks: getting allocated lines");
                        LineGeometry line = allocatedTicksList[i + usedTicks];
                        //PerformanceCounter.stopStopwatch("Minor ticks: getting allocated lines");
                        //PerformanceCounter.startStopwatch("Minor ticks: renewing allocated lines");
                        line.StartPoint = createScreenPoint1(screenCoord);;
                        line.EndPoint   = createScreenPoint2(screenCoord, sizes[i]);
                        //PerformanceCounter.stopStopwatch("Minor ticks: renewing allocated lines");
                    }
                    else
                    {
                        //PerformanceCounter.startStopwatch("Minor ticks: creating new lines");
                        LineGeometry line = new LineGeometry();
                        line.StartPoint = createScreenPoint1(screenCoord);;
                        line.EndPoint   = createScreenPoint2(screenCoord, sizes[i]);
                        geomGroup.Children.Add(line);
                        allocatedTicksList.Add(line);
                        //PerformanceCounter.stopStopwatch("Minor ticks: creating new lines");
                    }
                }
                usedTicks += screenCoords.Length;
            }
        }