LiveCharts.Charts.ChartCore.StackPoints C# (CSharp) Method

StackPoints() protected method

Stacks the points.
protected StackPoints ( IEnumerable stackables, AxisOrientation stackAt, int stackIndex, StackMode mode = StackMode.Values ) : void
stackables IEnumerable The stackables.
stackAt AxisOrientation The stack at.
stackIndex int Index of the stack.
mode StackMode The mode.
return void
        protected void StackPoints(IEnumerable<ISeriesView> stackables, AxisOrientation stackAt, int stackIndex,
            StackMode mode = StackMode.Values)
        {
            var stackedColumns = stackables.SelectMany(x => x.ActualValues.GetPoints(x))
                .GroupBy(x => stackAt == AxisOrientation.X ? x.Y : x.X);

            double mostLeft = 0, mostRight = 0;

            foreach (var column in stackedColumns)
            {
                double sumLeft = 0, sumRight = 0;

                foreach (var item in column)
                {
                    var s = stackAt == AxisOrientation.X ? item.X : item.Y;
                    if (s < 0)
                        sumLeft += s;
                    else
                        sumRight += s;
                }

                var lastLeft = 0d;
                var lastRight = 0d;
                var leftPart = 0d;
                var rightPart = 0d;

                foreach (var point in column)
                {
                    var pulled = stackAt == AxisOrientation.X ? point.X : point.Y;

                    //notice using (pulled < 0) or (pulled <= 0) could cause an issue similar to
                    //https://github.com/beto-rodriguez/Live-Charts/issues/231
                    //from that issue I changed <= to <
                    //only because it is more common to use positive values than negative
                    //you could face a similar issue if you are stacking only negative values
                    //a work around is forcing (pulled < 0) to be true,
                    //instead of using zero values, use -0.000000001/

                    if (pulled < 0)
                    {
                        point.From = lastLeft;
                        point.To = lastLeft + pulled;
                        point.Sum = sumLeft;
                        point.Participation = (point.To - point.From) / point.Sum;
                        point.Participation = double.IsNaN(point.Participation)
                            ? 0
                            : point.Participation;
                        leftPart += point.Participation;
                        point.StackedParticipation = leftPart;

                        lastLeft = point.To;
                    }
                    else
                    {
                        point.From = lastRight;
                        point.To = lastRight + pulled;
                        point.Sum = sumRight;
                        point.Participation = (point.To - point.From) / point.Sum;
                        point.Participation = double.IsNaN(point.Participation)
                            ? 0
                            : point.Participation;
                        rightPart += point.Participation;
                        point.StackedParticipation = rightPart;

                        lastRight = point.To;
                    }
                }

                if (sumLeft < mostLeft) mostLeft = sumLeft;
                if (sumRight > mostRight) mostRight = sumRight;
            }

            if (stackAt == AxisOrientation.X)
            {
                if (mode == StackMode.Percentage)
                {
                    AxisX[stackIndex].BotLimit = 0;
                    AxisX[stackIndex].TopLimit = 1;
                }
                else
                {
                    if (mostLeft < AxisX[stackIndex].BotLimit)
                        // ReSharper disable once CompareOfFloatsByEqualityOperator
                        AxisX[stackIndex].BotLimit = mostLeft == 0
                            ? 0
                            : ((int) (mostLeft/AxisX[stackIndex].S) - 1)*AxisX[stackIndex].S;
                    if (mostRight > AxisX[stackIndex].TopLimit)
                        // ReSharper disable once CompareOfFloatsByEqualityOperator
                        AxisX[stackIndex].TopLimit = mostRight == 0
                            ? 0
                            : ((int) (mostRight/AxisX[stackIndex].S) + 1)*AxisX[stackIndex].S;
                }
            }

            if (stackAt == AxisOrientation.Y)
            {
                if (mode == StackMode.Percentage)
                {
                    AxisY[stackIndex].BotLimit = 0;
                    AxisY[stackIndex].TopLimit = 1;
                }
                else
                {
                    if (mostLeft < AxisY[stackIndex].BotLimit)
                        // ReSharper disable once CompareOfFloatsByEqualityOperator
                        AxisY[stackIndex].BotLimit = mostLeft == 0
                            ? 0
                            : ((int) (mostLeft/AxisY[stackIndex].S) - 1)*AxisY[stackIndex].S;
                    if (mostRight > AxisY[stackIndex].TopLimit)
                        // ReSharper disable once CompareOfFloatsByEqualityOperator
                        AxisY[stackIndex].TopLimit = mostRight == 0
                            ? 0
                            : ((int) (mostRight/AxisY[stackIndex].S) + 1)*AxisY[stackIndex].S;
                }
            }
        }