protected void StackPoints(IEnumerable <ISeriesView> stackables, AxisOrientation stackAt, int stackIndex, StackMode mode = StackMode.Values) { var stackedColumns = stackables.Select(x => x.ActualValues.GetPoints(x).ToArray()).ToArray(); var maxI = stackedColumns.Select(x => x.Length).DefaultIfEmpty(0).Max(); for (var i = 0; i < maxI; i++) { var cols = stackedColumns .Select(x => x.Length > i ? new StackedSum(Pull(x[i], stackAt)) : new StackedSum()).ToArray(); var sum = new StackedSum { Left = cols.Select(x => x.Left).DefaultIfEmpty(0).Sum(), Right = cols.Select(x => x.Right).DefaultIfEmpty(0).Sum() }; if (stackAt == AxisOrientation.X) { if (mode == StackMode.Percentage) { AxisX[stackIndex].BotLimit = 0; AxisX[stackIndex].TopLimit = 1; } else { if (sum.Left < AxisX[stackIndex].BotLimit) { // ReSharper disable once CompareOfFloatsByEqualityOperator AxisX[stackIndex].BotLimit = sum.Left == 0 ? 0 : ((int)(sum.Left / AxisX[stackIndex].S) - 1) * AxisX[stackIndex].S; } if (sum.Right > AxisX[stackIndex].TopLimit) { // ReSharper disable once CompareOfFloatsByEqualityOperator AxisX[stackIndex].TopLimit = sum.Right == 0 ? 0 : ((int)(sum.Right / 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 (sum.Left < AxisY[stackIndex].BotLimit) { // ReSharper disable once CompareOfFloatsByEqualityOperator AxisY[stackIndex].BotLimit = sum.Left == 0 ? 0 : ((int)(sum.Left / AxisY[stackIndex].S) - 1) * AxisY[stackIndex].S; } if (sum.Right > AxisY[stackIndex].TopLimit) { // ReSharper disable once CompareOfFloatsByEqualityOperator AxisY[stackIndex].TopLimit = sum.Right == 0 ? 0 : ((int)(sum.Right / AxisY[stackIndex].S) + 1) * AxisY[stackIndex].S; } } } var lastLeft = 0d; var lastRight = 0d; var leftPart = 0d; var rightPart = 0d; foreach (var col in stackedColumns) { if (i >= col.Length) { continue; } var point = col[i]; var pulled = Pull(point, stackAt); //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 = sum.Left; 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 = sum.Right; 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; } } } }
protected void StackPoints(IEnumerable <ISeriesView> stackables, AxisTags stackAt, int stackIndex, StackMode mode = StackMode.Values) { var stackedColumns = stackables.Select(x => x.Values.Points.ToArray()).ToArray(); var maxI = stackedColumns.Select(x => x.Length).DefaultIfEmpty(0).Max(); for (var i = 0; i < maxI; i++) { var cols = stackedColumns .Select(x => x.Length > i ? new StackedSum(Pull(x[i], stackAt)) : new StackedSum()).ToArray(); var sum = new StackedSum { Left = cols.Select(x => x.Left).DefaultIfEmpty(0).Sum(), Right = cols.Select(x => x.Right).DefaultIfEmpty(0).Sum() }; if (stackAt == AxisTags.X) { if (mode == StackMode.Percentage) { AxisX[stackIndex].MinLimit = 0; AxisX[stackIndex].MaxLimit = 1; } else { if (sum.Left < AxisX[stackIndex].MinLimit) { AxisX[stackIndex].MinLimit = sum.Left == 0 ? 0 : ((int)(sum.Left / AxisX[stackIndex].S) - 1) * AxisX[stackIndex].S; } if (sum.Right > AxisX[stackIndex].MaxLimit) { AxisX[stackIndex].MaxLimit = sum.Right == 0 ? 0 : ((int)(sum.Right / AxisX[stackIndex].S) + 1) * AxisX[stackIndex].S; } } } if (stackAt == AxisTags.Y) { if (mode == StackMode.Percentage) { AxisY[stackIndex].MinLimit = 0; AxisY[stackIndex].MaxLimit = 1; } else { if (sum.Left < AxisY[stackIndex].MinLimit) { AxisY[stackIndex].MinLimit = sum.Left == 0 ? 0 : ((int)(sum.Left / AxisY[stackIndex].S) - 1) * AxisY[stackIndex].S; } if (sum.Right > AxisY[stackIndex].MaxLimit) { AxisY[stackIndex].MaxLimit = sum.Right == 0 ? 0 : ((int)(sum.Right / AxisY[stackIndex].S) + 1) * AxisY[stackIndex].S; } } } var lastLeft = 0d; var lastRight = 0d; var leftPart = 0d; var rightPart = 0d; foreach (var col in stackedColumns) { if (i >= col.Length) { continue; } var point = col[i]; var pulled = Pull(point, stackAt); if (pulled <= 0) { point.From = lastLeft; point.To = lastLeft + pulled; point.Sum = sum.Left; 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 = sum.Right; 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; } } } }