public static List <double> GetNiceLineData(IEnumerable <double> data, int order)
        {
            List <double> xdata = new List <double>();

            for (int i = 0; i < data.Count(); i++)
            {
                xdata.Add(i);
            }

            if (xdata.Count < 4)
            {
                return(new List <double>());
            }

            if (xdata.Count() < order)
            {
                order = Math.Max(xdata.Count() - 2, 3);
            }

            var poly = Fit.PolynomialFunc(xdata.ToArray(), data.ToArray(), order);

            List <double> nicedata = new List <double>();

            for (int i = 0; i < data.Count(); i++)
            {
                nicedata.Add(Math.Round(poly(i), 2));
            }

            return(nicedata);
        }
        public DebugDrawPathCurve FitPath(List <Vector2> path, int windowSizeCount, int polynomialOrder)
        {
            var windowSize        = new WindowSize(windowSizeCount);
            var subCurveFunctions = new List <CurveFunc>();

            for (int i = 0; i <= path.Count - windowSize.FullSize; i++)
            {
                var subcurvePoints = path.Skip(i).Take(windowSize.FullSize).ToList();

                var xArray = subcurvePoints.Select(c => (double)c.x).ToArray();
                var yArray = subcurvePoints.Select(c => (double)c.y).ToArray();
                var tArray = Enumerable.Range(0, subcurvePoints.Count)
                             .Select(c => (double)c / (subcurvePoints.Count - 1)).ToArray();

                var xFunc = Fit.PolynomialFunc(tArray, xArray, polynomialOrder);
                var yFunc = Fit.PolynomialFunc(tArray, yArray, polynomialOrder);

                subCurveFunctions.Add(new CurveFunc((t) => new Vector2((float)xFunc(t), (float)yFunc(t))));
            }

            return(new DebugDrawPathCurve()
            {
                FinalCurve = PathCurve.Create(path, subCurveFunctions, windowSizeCount),
                SubCurves = subCurveFunctions
            });
        }
示例#3
0
        public void FitsToOrder2PolynomialSameAsExcelTrendLine()
        {
            // X	Y
            // 1   0.2
            // 2   0.3
            // 4   1.3
            // 6   4.2
            // -> y = 0.7101 - 0.6675*x + 0.2077*x^2

            var x = new[] { 1.0, 2.0, 4.0, 6.0 };
            var y = new[] { 0.2, 0.3, 1.3, 4.2 };

            var resp = Fit.Polynomial(x, y, 2);

            Assert.AreEqual(0.7101, resp[0], 1e-3);
            Assert.AreEqual(-0.6675, resp[1], 1e-3);
            Assert.AreEqual(0.2077, resp[2], 1e-3);

            var resf = Fit.PolynomialFunc(x, y, 2);

            foreach (var z in Enumerable.Range(-3, 10))
            {
                Assert.AreEqual(0.7101 - 0.6675 * z + 0.2077 * z * z, resf(z), 1e-2);
            }
        }
示例#4
0
        /********************************************************************************************
        * Constructors
        ********************************************************************************************/

        public PolynomApproximation(
            double[] x,
            double[] y,
            int order
            )
        {
            GetValue = Fit.PolynomialFunc(x, y, order);
        }
示例#5
0
        private void LinearFitting()
        {
            var points  = dataSource.GetPoints;
            var xPoints = points.Select(p => p.X).ToList();
            var yPoints = points.Select(p => p.Y).ToList();
            var fitFunc = Fit.PolynomialFunc(xPoints.ToArray(), yPoints.ToArray(), 1);

            PopulateFittingPoints(fitFunc);
        }
示例#6
0
        /*
         * Not working correcty
         */
        public static double[] simpleInterpol(double[] x, double[] y)
        {
            double[] curve = new double[(int)x[x.Length - 1]];
            var      f     = Fit.PolynomialFunc(x, y, 3);

            for (int i = 0; i < curve.Length; i++)
            {
                curve[i] = f(i);
            }
            return(curve);
        }
        private Func <double, double> CalculateRegressionFunction(TimeSeriesByDay timeSeriesByDay)
        {
            var daysDataForPrediction = timeSeriesByDay.DaysWithLocationData
                                        .Skip(1).ToArray();

            var xData = daysDataForPrediction.Select(dayData => (double)dayData.DayNumber).ToArray();
            var yData = daysDataForPrediction.Select(dayData => (double)dayData.NewCases).ToArray();

            var regressionFunction = Fit.PolynomialFunc(xData, yData, 2);

            return(regressionFunction);
        }
示例#8
0
        public Func <double, double> MakeInterpolator(IEnumerable <double> x, IEnumerable <double> y)
        {
            SplineBoundaryCondition bc;
            int xlength = x.Count();
            int mode    = InterpolationModeComboBox.SelectedIndex;

            if (mode == 0 || mode == 1)
            {
                int order;
                order = mode * 2 + 1; // linear => 1; cubic => 3
                int npoints;
                if (!int.TryParse(extrapolationPointsTextBox.Text, out npoints))
                {
                    throw new Exception("Cannot parse number of points");
                }
                if (npoints > xlength)
                {
                    throw new Exception("Too many points required");
                }
                if (npoints < order)
                {
                    throw new Exception("More points must be used");
                }
                var leftInterp = Fit.PolynomialFunc(x.Take(npoints).ToArray(), y.Take(npoints).ToArray(),
                                                    order);
                var rightInterp = Fit.PolynomialFunc(x.Reverse().Take(npoints).Reverse().ToArray(),
                                                     y.Reverse().Take(npoints).Reverse().ToArray(),
                                                     order);
                double middlex = x.Skip((int)(xlength / 2)).First();
                return(x2 => (x2 < middlex)?leftInterp(x2) : rightInterp(x2));
            }
            else if (mode == 5)
            {
                IInterpolation I = LinearSpline.Interpolate(x, y);
                return(x2 => I.Interpolate(x2));
            }
            else
            {
                if (InterpolationModeComboBox.SelectedIndex == 1)
                {
                    bc = SplineBoundaryCondition.ParabolicallyTerminated;
                }
                else
                {
                    bc = SplineBoundaryCondition.Natural;
                }

                IInterpolation I = CubicSpline.InterpolateBoundaries(
                    x, y,
                    bc, 0, bc, 0); // Values are unused for natural and parabolic termination
                return(x2 => I.Interpolate(x2));
            }
        }
示例#9
0
        /*
         * Not working correcty
         */
        public static double[] SimpleInterpol(double[] xCoordinates, double[] yCoordinates)
        {
            Debug.Assert(xCoordinates.Length >= 2);
            Debug.Assert(yCoordinates.Length >= 2);
            Debug.Assert(xCoordinates.Length == yCoordinates.Length);
            double[] curve = new double[(int)xCoordinates[xCoordinates.Length - 1]];
            var      f     = Fit.PolynomialFunc(xCoordinates, yCoordinates, 3);

            for (int i = 0; i < curve.Length; i++)
            {
                curve[i] = f(i);
            }
            return(curve);
        }
示例#10
0
    public IObservable <double[]> Process(IObservable <Tuple <float, double>[]> source)
    {
        return(source.Select(value =>
        {
            var x = Generate.Map(value, v => v.Item2);
            var y = Generate.Map(value, v => (double)v.Item1);

            // var p = Fit.LogarithmFunc(y, x);
            var p = Fit.PolynomialFunc(y, x, 6);
            var vmax = MathNet.Numerics.Statistics.ArrayStatistics.Maximum(y);

            // var p = Fit.Logarithm(y, x);
            //  return  Generate.Map(x, v => p.Item1 + p.Item2 * Math.Log(v));
            return Generate.Map(x, v => Math.Max(0, p(v * vmax)));
        }));
    }
示例#11
0
        public void FitsToLineOnOrder1Polynomial()
        {
            // Mathematica: Fit[{{1,4.986},{2,2.347},{3,2.061},{4,-2.995},{5,-2.352},{6,-5.782}}, {1, x}, x]
            // -> 7.01013 - 2.08551 x

            var x = Enumerable.Range(1, 6).Select(Convert.ToDouble).ToArray();
            var y = new[] { 4.986, 2.347, 2.061, -2.995, -2.352, -5.782 };

            var resp = Fit.Polynomial(x, y, 1);

            Assert.AreEqual(2, resp.Length);
            Assert.AreEqual(7.01013, resp[0], 1e-4);
            Assert.AreEqual(-2.08551, resp[1], 1e-4);

            var resf = Fit.PolynomialFunc(x, y, 1);

            foreach (var z in Enumerable.Range(-3, 10))
            {
                Assert.AreEqual(7.01013 - 2.08551 * z, resf(z), 1e-4);
            }
        }
示例#12
0
        public void FitsToOrder2Polynomial()
        {
            // Mathematica: Fit[{{1,4.986},{2,2.347},{3,2.061},{4,-2.995},{5,-2.352},{6,-5.782}}, {1, x, x^2}, x]
            // -> 6.9703 - 2.05564 x - 0.00426786 x^2

            var x = Enumerable.Range(1, 6).Select(Convert.ToDouble).ToArray();
            var y = new[] { 4.986, 2.347, 2.061, -2.995, -2.352, -5.782 };

            var resp = Fit.Polynomial(x, y, 2);

            Assert.AreEqual(3, resp.Length);
            Assert.AreEqual(6.9703, resp[0], 1e-4);
            Assert.AreEqual(-2.05564, resp[1], 1e-4);
            Assert.AreEqual(-0.00426786, resp[2], 1e-6);

            var resf = Fit.PolynomialFunc(x, y, 2);

            foreach (var z in Enumerable.Range(-3, 10))
            {
                Assert.AreEqual(Evaluate.Polynomial(z, resp), resf(z), 1e-4);
            }
        }
示例#13
0
 public virtual Func <double, double> PolynomialFittingFunc(double[] x, double[] y, int order)
 {
     return(Fit.PolynomialFunc(x, y, order));
 }
示例#14
0
        public static DataResult GetTimeLine(DSoptions _options, DSReplayContext _context, IJSRuntime _jsRuntime, object lockobject)
        {
            if (String.IsNullOrEmpty(_options.Interest))
            {
                return(new DataResult());
            }

            var replays = DBReplayFilter.Filter(_options, _context, false);

            var result = (_options.Player, _options.Dataset.Any()) switch
            {
                (true, false) => from r in replays
                from p in r.DSPlayer
                where p.RACE == _options.Interest && p.NAME.Length == 64
                select new
                {
                    r.ID,
                    r.GAMETIME,
                    p.WIN
                },
                (true, true) => from r in replays
                from p in r.DSPlayer
                where p.RACE == _options.Interest && _options.Dataset.Contains(p.NAME)
                select new
                {
                    r.ID,
                    r.GAMETIME,
                    p.WIN
                },
                _ => from r in replays
                from p in r.DSPlayer
                where p.RACE == _options.Interest
                select new
                {
                    r.ID,
                    r.GAMETIME,
                    p.WIN
                }
            };
            var lresult = result.OrderBy(o => o.GAMETIME).ToList();

            if (!lresult.Any())
            {
                return(new DataResult());
            }

            CultureInfo           provider = CultureInfo.InvariantCulture;
            DataResult            dresult  = new DataResult();
            List <double>         data     = new List <double>();
            List <double>         xdata    = new List <double>();
            List <double>         ydata    = new List <double>();
            List <string>         labels   = new List <string>();
            Func <double, double> f        = null;

            int count = lresult.Count;
            int step  = 50;
            int cstep = count / step;

            while (cstep < 10)
            {
                step -= 1;
                cstep = count / step;
                if (step <= 1)
                {
                    break;
                }
            }
            dresult.CmdrInfo.Wins      = lresult.Where(x => x.WIN == true).Count();
            dresult.CmdrInfo.Games     = count;
            dresult.CmdrInfo.AWinrate  = Math.Round((double)dresult.CmdrInfo.Wins * 100 / dresult.CmdrInfo.Games, 2);
            dresult.CmdrInfo.ADuration = TimeSpan.FromDays(cstep);
            dresult.CmdrInfo.GameIDs   = lresult.Select(s => s.ID).ToHashSet();


            for (int i = 0; i < step; i++)
            {
                var sreps = lresult.Skip(i * cstep).Take(cstep);
                if (!sreps.Any())
                {
                    continue;
                }
                data.Add(Math.Round((double)sreps.Where(x => x.WIN == true).Count() * 100 / (double)sreps.Count(), 2));
                labels.Add(sreps.Last().GAMETIME.ToString("yyyy-MM-dd"));
                xdata.Add(i);
                ydata.Add(data.Last());
            }

            if (xdata.Any() && xdata.Count > 1)
            {
                int order = 6;
                if (xdata.Count <= 6)
                {
                    if (xdata.Count < 3)
                    {
                        order = 1;
                    }
                    else
                    {
                        order = xdata.Count - 2;
                    }
                }
                f = Fit.PolynomialFunc(xdata.ToArray(), ydata.ToArray(), order);
            }

            dresult.Labels       = labels;
            dresult.Dataset.data = data;
            dresult.fTimeline    = f;
            dresult.fStartTime   = lresult.First().GAMETIME;

            ChartService.SetColor(dresult.Dataset, _options.Chart.type, _options.Interest);
            dresult.Dataset.fill             = false;
            dresult.Dataset.pointRadius      = 2;
            dresult.Dataset.pointHoverRadius = 10;
            dresult.Dataset.showLine         = false;
            for (int i = 0; i < dresult.Labels.Count; i++)
            {
                ChartJSInterop.AddData(_jsRuntime,
                                       dresult.Labels[i],
                                       dresult.Dataset.data[i],
                                       dresult.Dataset.backgroundColor.Last(),
                                       null,
                                       lockobject
                                       ).GetAwaiter();
            }
            if (dresult.fTimeline != null)
            {
                string   fstart  = dresult.Labels.First().Substring(0, 10);
                DateTime ffstart = DateTime.ParseExact(fstart, "yyyy-MM-dd", provider);

                ChartJSdataset dataset = new ChartJSdataset();
                dataset.label       = _options.Interest + "_line";
                dataset.borderWidth = 3;
                dataset.pointRadius = 1;
                ChartService.SetColor(dataset, _options.Chart.type, _options.Interest);
                dataset.backgroundColor.Clear();
                _options.Chart.data.datasets.Add(dataset);
                ChartJSInterop.AddDataset(_jsRuntime, JsonConvert.SerializeObject(dataset, Formatting.Indented), lockobject).GetAwaiter();

                for (int i = 0; i < dresult.Labels.Count; i++)
                {
                    double fdata = dresult.fTimeline(i);

                    ChartJSInterop.AddData(_jsRuntime,
                                           dresult.Labels[i],
                                           fdata,
                                           dresult.Dataset.backgroundColor.Last(),
                                           null,
                                           lockobject
                                           ).GetAwaiter();
                }
            }
            return(dresult);
        }
示例#15
0
        private void calculateMemoryAllocations()
        {
            foreach (EssesFileCacheContext fileCache in this.fileCaches.Values)
            {
                List <IInterpolation> utilities = new List <IInterpolation>();
                List <UInt64>         minNecessaryAllocations = new List <UInt64>();
                List <UInt64>         finalAllocations        = new List <UInt64>();

                UInt64 epsilon = 1048576; //Water-filling constant ; XXIS: PICK A GOOD VALUE FOR THIS

                List <uint> flowsInAllocation = new List <uint>();
                foreach (Flow flow in fileCache.flows)
                {
                    EssesFlowCacheContext flowCacheContext = (EssesFlowCacheContext)flow.Context;

                    UInt64 flowBWSLA = flowCacheContext.guaranteedE2EBW;
                    double numerator = (double)(flowBWSLA - this.remoteStorageBW);
                    double deminator = (double)(this.localCacheBW - this.remoteStorageBW);

                    double necessaryHitRate = numerator / deminator;

                    Double[] newYVals = new Double[flowCacheContext.cacheDemandCurvePoints.yVals.Length];

                    for (int j = 0; j < flowCacheContext.cacheDemandCurvePoints.yVals.Length; j++)
                    {
                        newYVals[j] = necessaryHitRate - flowCacheContext.cacheDemandCurvePoints.yVals[j];
                    }

                    Func <double, double> rootFunc = Fit.PolynomialFunc(flowCacheContext.cacheDemandCurvePoints.xVals, newYVals, 10);


                    //double reqCacheSize = MathNet.Numerics.RootFinding.Bisection.FindRoot(rootFunc, 0, (double)fileCache.fileCacheSize);
                    double reqCacheSize; // = MathNet.Numerics.RootFinding.RobustNewtonRaphson.FindRoot(rootFunc, Differentiate.FirstDerivativeFunc(rootFunc), 0, (double)fileCache.fileCacheSize, 1e-3);

                    if (MathNet.Numerics.RootFinding.RobustNewtonRaphson.TryFindRoot(rootFunc, Differentiate.FirstDerivativeFunc(rootFunc), 0, (double)fileCache.fileCacheSize, 1e-3, 100, 20, out reqCacheSize))
                    {
                    }

                    utilities.Add(flowCacheContext.cacheDemandFunc);
                    minNecessaryAllocations.Add((UInt64)reqCacheSize);
                    flowsInAllocation.Add(flow.FlowId);
                }


                UtilityMaximizationAllocation(fileCache.fileCacheSize, utilities, minNecessaryAllocations, epsilon, finalAllocations);

                int i = 0; //counter for flows that were allocated cache this iteration (with flowIDs in flowsInAllocation)
                foreach (Flow flow in fileCache.flows)
                {
                    string responseString         = "";
                    EssesFlowCacheContext context = (EssesFlowCacheContext)flow.Context;

                    if (flowsInAllocation.Contains(flow.FlowId))
                    {
                        if (finalAllocations[i] != context.cacheSizeAllocated)
                        {
                            //Response string example; commands to cache module can be any number of the commands below in the same message (in any order)
                            responseString            += "changeCacheSize=" + finalAllocations[i].ToString() + " ";
                            context.cacheSizeAllocated = finalAllocations[i]; //update our own state of the new flow cache size

                            //if we changed the cache size, reset the counters to compute hit rate (client is doing so too)
                            context.cacheAccessesTotal     = 0;
                            context.cacheAccessesHitsTotal = 0;
                        }
                        i++; //only increment when we see a flow we allocated cache to
                    }
                    else //flow is idle; not included in cache allocation
                    {
                        if (context.cacheSizeAllocated != 0)
                        {
                            responseString            += "changeCacheSize=0";
                            context.cacheSizeAllocated = 0; //update our own state of the new flow cache size

                            //if we changed the cache size, reset the counters to compute hit rate (client is doing so too)
                            context.cacheAccessesTotal     = 0;
                            context.cacheAccessesHitsTotal = 0;
                        }
                    }

                    //ADD WHATEVER OTHER PARAMETERS YOU WANT TO CHANGE THE CLIENT CACHE HERE
                    flow.IoFlowUpdateParams = responseString; //XXXIS: parameters to update flow get put in responseString
                }
            }
        }
示例#16
0
        static void Main(string[] args)
        {
            //首先生成 x 点的向量,在区间 [0,2.5] 内等间距分布;然后计算这些点处的 erf(x)。
            //double[] x = Generate.LinearRange(start: 0, step: 0.1, stop: 2.5);
            double[]      x = Generate.LinearRange(start: 1, step: 1, stop: 10);
            List <double> y = new List <double>();

            foreach (double x0 in x)
            {
                y.Add(SpecialFunctions.Erf(x0));
            }
            //确定 6 阶逼近多项式的系数。
            double[] p = Fit.Polynomial(x, y.ToArray(), order: 6);
            Write("p = ");
            foreach (double coefficient in p)
            {
                Write($"{coefficient:F2} ");
            }
            WriteLine();
            //为了查看拟合情况如何,在各数据点处计算多项式,并生成说明数据、拟合和误差的一个表。
            WriteLine();
            var funcP = Fit.PolynomialFunc(x, y.ToArray(), 6);

            WriteLine($"{"x",10}|{"y",10}|{"Fit",10}|{"FitError",10}");
            WriteLine($"{new string('-', 10)}|{new string('-', 10)}|{new string('-', 10)}|{new string('-', 10)}");
            foreach (double x0 in Generate.LinearRange(1, 1, 10))
            {
                double y0       = SpecialFunctions.Erf(x0);
                double fit      = funcP(x0);
                double fitError = fit - y0;
                WriteLine($"{x0,10:F2}|{y0,10:F2}|{fit,10:F2}|{fitError,10:F2}");
            }
            ReadKey();



            /*
             *
             * using MathNet.Numerics;
             * using System.Collections.Generic;
             * using static System.Console;
             *
             * namespace ConsoleApp1
             * {
             * class Program
             * {
             * static void Main()
             * {
             * //首先生成 x 点的向量,在区间 [0,2.5] 内等间距分布;然后计算这些点处的 erf(x)。
             * double[] x = Generate.LinearRange(start: 0, step: 0.1, stop: 2.5);
             * List<double> y = new List<double>();
             * foreach (double x0 in x)
             * {
             *  y.Add(SpecialFunctions.Erf(x0));
             * }
             * //确定 6 阶逼近多项式的系数。
             * double[] p = Fit.Polynomial(x, y.ToArray(), order: 6);
             * Write("p = ");
             * foreach (double coefficient in p)
             * {
             *  Write($"{coefficient:F5} ");
             * }
             * WriteLine();
             * //为了查看拟合情况如何,在各数据点处计算多项式,并生成说明数据、拟合和误差的一个表。
             * WriteLine();
             * var funcP = Fit.PolynomialFunc(x, y.ToArray(), 6);
             * WriteLine($"{"x",10}|{"y",10}|{"Fit",10}|{"FitError",10}");
             * WriteLine($"{new string('-', 10)}|{new string('-', 10)}|{new string('-', 10)}|{new string('-', 10)}");
             * foreach (double x0 in Generate.LinearRange(0, 0.1, 1.5))
             * {
             *  double y0 = SpecialFunctions.Erf(x0);
             *  double fit = funcP(x0);
             *  double fitError = fit - y0;
             *  WriteLine($"{x0,10:F4}|{y0,10:F4}|{fit,10:F4}|{fitError,10:F4}");
             * }
             * }
             * }
             * }
             */
        }
示例#17
0
        public static DataResult GetDurations(DSoptions _options, DSReplayContext _context, IJSRuntime _jsRuntime, object lockobject)
        {
            if (String.IsNullOrEmpty(_options.Interest))
            {
                return(new DataResult());
            }

            var replays = DBReplayFilter.Filter(_options, _context, false);

            var result = (_options.Player, _options.Dataset.Any()) switch
            {
                (true, false) => from r in replays
                from p in r.DSPlayer
                where p.RACE == _options.Interest && p.NAME.Length == 64
                select new
                {
                    r.ID,
                    r.DURATION,
                    p.WIN
                },
                (true, true) => from r in replays
                from p in r.DSPlayer
                where p.RACE == _options.Interest && _options.Dataset.Contains(p.NAME)
                select new
                {
                    r.ID,
                    r.DURATION,
                    p.WIN
                },
                _ => from r in replays
                from p in r.DSPlayer
                where p.RACE == _options.Interest
                select new
                {
                    r.ID,
                    r.DURATION,
                    p.WIN
                }
            };
            var lresult = result.ToList();

            if (!lresult.Any())
            {
                return(new DataResult());
            }

            CultureInfo           provider = CultureInfo.InvariantCulture;
            DataResult            dresult  = new DataResult();
            List <double>         data     = new List <double>();
            List <double>         xdata    = new List <double>();
            List <double>         ydata    = new List <double>();
            List <string>         labels   = new List <string>();
            Func <double, double> f        = null;

            int count = lresult.Count;

            dresult.CmdrInfo.Wins      = lresult.Where(x => x.WIN == true).Count();
            dresult.CmdrInfo.Games     = count;
            dresult.CmdrInfo.AWinrate  = Math.Round((double)dresult.CmdrInfo.Wins * 100 / dresult.CmdrInfo.Games, 2);
            dresult.CmdrInfo.ADuration = TimeSpan.FromDays(3);
            dresult.CmdrInfo.GameIDs   = lresult.Select(s => s.ID).ToHashSet();


            for (int i = 0; i < DSdata.s_durations.Length; i++)
            {
                double games  = 1;
                double wins   = 0;
                int    startd = 0;

                if (i > 0)
                {
                    Match m = d_rx.Match(DSdata.s_durations[i]);
                    if (m.Success)
                    {
                        startd = int.Parse(m.Value);
                    }
                }

                int endd = startd + 3;
                if (i == 0)
                {
                    endd = 8;
                }
                if (i == DSdata.s_durations.Length - 1)
                {
                    endd = 200;
                }

                var ilresult = lresult.Where(x => x.DURATION > startd * 60 && x.DURATION < endd * 60);
                games = ilresult.Count();
                wins  = ilresult.Where(x => x.WIN == true).Count();

                data.Add(Math.Round(wins * 100 / games, 2));
                labels.Add(DSdata.s_durations[i] + " min (" + games + ")");
                xdata.Add(i);
                ydata.Add(data.Last());
            }

            if (xdata.Any() && xdata.Count > 1)
            {
                int order = 3;
                if (xdata.Count <= 3)
                {
                    if (xdata.Count < 3)
                    {
                        order = 1;
                    }
                    else
                    {
                        order = xdata.Count - 2;
                    }
                }
                f = Fit.PolynomialFunc(xdata.ToArray(), ydata.ToArray(), order);
            }

            dresult.Labels       = labels;
            dresult.Dataset.data = data;
            dresult.fTimeline    = f;
            dresult.fStartTime   = DateTime.MinValue;

            ChartService.SetColor(dresult.Dataset, _options.Chart.type, _options.Interest);
            dresult.Dataset.fill             = false;
            dresult.Dataset.pointRadius      = 2;
            dresult.Dataset.pointHoverRadius = 10;
            dresult.Dataset.showLine         = false;
            for (int i = 0; i < dresult.Labels.Count; i++)
            {
                ChartJSInterop.AddData(_jsRuntime,
                                       dresult.Labels[i],
                                       dresult.Dataset.data[i],
                                       dresult.Dataset.backgroundColor.Last(),
                                       null,
                                       lockobject
                                       ).GetAwaiter();
            }
            if (dresult.fTimeline != null)
            {
                ChartJSdataset dataset = new ChartJSdataset();
                dataset.label       = _options.Interest + "_line";
                dataset.borderWidth = 3;
                dataset.pointRadius = 1;
                ChartService.SetColor(dataset, _options.Chart.type, _options.Interest);
                dataset.backgroundColor.Clear();
                _options.Chart.data.datasets.Add(dataset);
                ChartJSInterop.AddDataset(_jsRuntime, JsonConvert.SerializeObject(dataset, Formatting.Indented), lockobject).GetAwaiter();

                for (int i = 0; i < dresult.Labels.Count; i++)
                {
                    double fdata = dresult.fTimeline(i);

                    ChartJSInterop.AddData(_jsRuntime,
                                           dresult.Labels[i],
                                           fdata,
                                           dresult.Dataset.backgroundColor.Last(),
                                           null,
                                           lockobject
                                           ).GetAwaiter();
                }
            }
            return(dresult);
        }