private static double[] GenerateTickPositions(CoordinateRange range, PixelLength size, float predictedTickSize)
    {
        double unitsPerPx = range.Span / size.Length;

        float  tickDensity     = 1.0f;
        int    targetTickCount = (int)(size.Length / predictedTickSize * tickDensity);
        double tickSpacing     = GetIdealTickSpacing(range, targetTickCount);

        double firstTickOffset = range.Min % tickSpacing;
        int    tickCount       = (int)(range.Span / tickSpacing) + 2;

        tickCount = Math.Min(1000, tickCount);
        tickCount = Math.Max(1, tickCount);

        double[] majorTickPositions = Enumerable.Range(0, tickCount)
                                      .Select(x => range.Min - firstTickOffset + tickSpacing * x)
                                      .Where(x => range.Contains(x))
                                      .ToArray();

        if (majorTickPositions.Length < 2)
        {
            double tickBelow = range.Min - firstTickOffset;
            double firstTick = majorTickPositions.Length > 0 ? majorTickPositions[0] : tickBelow;
            double nextTick  = tickBelow + tickSpacing;
            majorTickPositions = new double[] { firstTick, nextTick };
        }

        return(majorTickPositions);
    }
    private static double[] MinorFromMajor(double[] majorTicks, double minorTicksPerMajorTick, CoordinateRange range)
    {
        if (majorTicks == null || majorTicks.Length < 2)
        {
            return new double[] { }
        }
        ;

        double majorTickSpacing = majorTicks[1] - majorTicks[0];
        double minorTickSpacing = majorTickSpacing / minorTicksPerMajorTick;

        List <double> majorTicksWithPadding = new()
        {
            majorTicks[0] - majorTickSpacing
        };

        majorTicksWithPadding.AddRange(majorTicks);

        List <double> minorTicks = new();

        foreach (var majorTickPosition in majorTicksWithPadding)
        {
            for (int i = 1; i < minorTicksPerMajorTick; i++)
            {
                double minorTickPosition = majorTickPosition + minorTickSpacing * i;
                if (range.Contains(minorTickPosition))
                {
                    minorTicks.Add(minorTickPosition);
                }
            }
        }

        return(minorTicks.ToArray());
    }
 public IEnumerable <Tick> GetVisibleTicks(CoordinateRange range)
 {
     return(Ticks.Where(x => range.Contains(x.Position)));
 }