private void AddBoxWhiskerAdornments(DoubleRange sbsInfo, double xValue, double minimum, double maximum, double x1, double median, double lowerQuartile, double upperQuartile, List <double> outliers, int index) { if (AdornmentsInfo != null) { ChartAdornment adornment = null; var sbsMedian = sbsInfo.Delta / 2; adornment = this.CreateAdornment(this, xValue, minimum, x1 + sbsMedian, minimum); adornment.ActualLabelPosition = bottomLabelPosition; adornment.Item = ActualData[index]; Adornments.Add(adornment); adornment = this.CreateAdornment(this, xValue, lowerQuartile, x1 + sbsMedian, lowerQuartile); adornment.ActualLabelPosition = bottomLabelPosition; adornment.Item = ActualData[index]; Adornments.Add(adornment); adornment = this.CreateAdornment(this, xValue, median, x1 + sbsMedian, median); adornment.ActualLabelPosition = topLabelPosition; adornment.Item = ActualData[index]; Adornments.Add(adornment); adornment = this.CreateAdornment(this, xValue, upperQuartile, x1 + sbsMedian, upperQuartile); adornment.ActualLabelPosition = topLabelPosition; adornment.Item = ActualData[index]; Adornments.Add(adornment); adornment = this.CreateAdornment(this, xValue, maximum, x1 + sbsMedian, maximum); adornment.ActualLabelPosition = topLabelPosition; adornment.Item = ActualData[index]; Adornments.Add(adornment); } }
private void AddStackingAreaAdornments(IList <double> yValues) { double adornX = 0d, adornY = 0d; int i = 0; List <double> xValues = null; IList <double> actualYValues = YValues; if (ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed) { xValues = GroupedXValuesIndexes; actualYValues = GroupedSeriesYValues[0]; } else { xValues = GetXValues(); } for (i = 0; i < xValues.Count; i++) { adornX = xValues[i]; adornY = yValues[i]; if (i < Adornments.Count) { Adornments[i].SetData(adornX, actualYValues[i], adornX, adornY); } else { Adornments.Add(this.CreateAdornment(this, adornX, actualYValues[i], adornX, adornY)); } Adornments[i].Item = ActualData[i]; } }
/// <summary> /// Method implementation for Add ColumnAdornments in Chart. /// </summary> /// <param name="values">The Value</param> protected virtual void AddColumnAdornments(params double[] values) { // values[0] --> xData // values[1] --> yData // values[2] --> xPos // values[3] --> yPos // values[4] --> data point index // values[5] --> Median value. double adornposX = values[2] + values[5], adornposY = values[3]; var pointIndex = (int)values[4]; if (pointIndex < Adornments.Count) { Adornments[pointIndex].SetData(values[0], values[1], adornposX, adornposY, values[6]); } else { Adornments.Add(this.CreateAdornment(this, values[0], values[1], adornposX, adornposY, values[6])); } if (ActualXAxis is CategoryAxis3D && !(ActualXAxis as CategoryAxis3D).IsIndexed) { Adornments[pointIndex].Item = this.GroupedActualData[pointIndex]; } else { Adornments[pointIndex].Item = this.ActualData[pointIndex]; } }
private void AddPieAdornments(double x, double y, double startAngle, double endAngle, int i, int index, PieSegment pieSegment) { double angle = (startAngle + endAngle) / 2; if (Area == null || Area.RootPanelDesiredSize == null || Area.RootPanelDesiredSize.Value == null) { return; } var actualheight = Area.RootPanelDesiredSize.Value.Height; var actualwidth = Area.RootPanelDesiredSize.Value.Width; var pieSeries = (from series in Area.VisibleSeries where series is PieSeries select series).ToList(); var pieSeriesCount = pieSeries.Count(); double pieIndex = pieSeries.IndexOf(this); double actualRadius = (Math.Min(actualwidth, actualheight)) / 2; double equalParts = actualRadius / (pieSeriesCount); double radius = (equalParts * (pieIndex + 1)) - (equalParts * (1 - InternalPieCoefficient)); if (index < Adornments.Count) { (Adornments[index] as ChartPieAdornment).SetData(x, y, angle, radius); } else { Adornments.Add(this.CreateAdornment(this, x, y, angle, radius)); } Adornments[index].Item = !double.IsNaN(GroupTo) ? Segments[index].Item : ActualData[index]; }
/// <summary> /// Creates the segments of FastLineSeries. /// </summary> public override void CreateSegments() { if (GroupedSeriesYValues != null && GroupedSeriesYValues[0].Contains(double.NaN)) { List <List <double> > yValList; List <List <double> > xValList; this.CreateEmptyPointSegments(GroupedSeriesYValues[0], out yValList, out xValList); } else if (YValues.Contains(double.NaN)) { List <List <double> > yValList; List <List <double> > xValList; this.CreateEmptyPointSegments(YValues, out yValList, out xValList); } else { bool isGrouping = this.ActualXAxis is CategoryAxis ? (this.ActualXAxis as CategoryAxis).IsIndexed : true; if (!isGrouping) { xValues = GroupedXValuesIndexes; } else { xValues = (ActualXValues is IList <double> && !IsIndexed) ? ActualXValues as IList <double> : GetXValues(); } if (!isGrouping) { Segments.Clear(); Adornments.Clear(); if (Segment == null || Segments.Count == 0) { FastLineSegment segment = new FastLineSegment(xValues, GroupedSeriesYValues[0], this); Segment = segment; Segments.Add(segment); } } else { ClearUnUsedAdornments(this.DataCount); if (Segment == null || Segments.Count == 0) { FastLineSegment segment = new FastLineSegment(xValues, YValues, this); Segment = segment; Segments.Add(segment); } else if (ActualXValues != null) { Segment.SetData(xValues, YValues); (Segment as FastLineSegment).SetRange(); Segment.Item = ActualData; } } isAdornmentPending = true; } }
/// <summary> /// Adds the pie adornments. /// </summary> /// <param name="x">The X Value</param> /// <param name="y">The Y Value</param> /// <param name="startAngle">The Start Angle</param> /// <param name="endAngle">The End Angle</param> /// <param name="index">The Index</param> /// <param name="radius">The Radius</param> /// <param name="startDepth">The Start Depth</param> private void AddPieAdornments(double x, double y, double startAngle, double endAngle, int index, double radius, double startDepth) { startAngle = CircularSeriesBase3D.DegreeToRadianConverter(startAngle); endAngle = DegreeToRadianConverter(endAngle); var angle = (startAngle + endAngle) / 2; Adornments.Add(PieSeries3D.CreateAdornment(this, x, y, angle, radius, startDepth)); Adornments[(int)x].Item = this.ActualData[index]; }
/// <summary> /// Called when DataSource property changed /// </summary> /// <param name="oldValue">The Old Value</param> /// <param name="newValue">The New Value</param> protected override void OnDataSourceChanged(IEnumerable oldValue, IEnumerable newValue) { if (this.AdornmentsInfo != null) { Adornments.Clear(); this.AdornmentsInfo.UpdateElements(); } base.OnDataSourceChanged(oldValue, newValue); }
/// <summary> /// Method implementation for Clear Unused Adornments /// </summary> /// <param name="startIndex"></param> protected void ClearUnUsedAdornments(int startIndex) { if (Adornments.Count > startIndex) { int count = Adornments.Count; for (int i = startIndex; i < count; i++) { Adornments.RemoveAt(startIndex); } } }
/// <summary> /// Called when VisibleRange property changed /// </summary> protected override void OnVisibleRangeChanged(VisibleRangeChangedEventArgs e) { if (AdornmentsInfo != null && isAdornmentPending) { if (xValues != null && ActualXAxis != null && !ActualXAxis.VisibleRange.IsEmpty) { double xBase = ActualXAxis.IsLogarithmic ? (ActualXAxis as LogarithmicAxis).LogarithmicBase : 1; bool xIsLogarithmic = ActualXAxis.IsLogarithmic; double start = ActualXAxis.VisibleRange.Start; double end = ActualXAxis.VisibleRange.End; for (int i = 0; i < DataCount; i++) { double x, y; if (this.ActualXAxis is CategoryAxis && !(this.ActualXAxis as CategoryAxis).IsIndexed) { if (i < xValues.Count) { y = GroupedSeriesYValues[0][i]; x = xValues[i]; } else { return; } } else { x = xValues[i]; y = YValues[i]; } double edgeValue = xIsLogarithmic ? Math.Log(x, xBase) : x; if (edgeValue >= start && edgeValue <= end && !double.IsNaN(y)) { if (i < Adornments.Count) { Adornments[i].SetData(x, y, x, y); Adornments[i].Item = ActualData[i]; } else { Adornments.Add(this.CreateAdornment(this, x, y, x, y)); Adornments[Adornments.Count - 1].Item = ActualData[i]; } } } } isAdornmentPending = false; } }
/// <summary> /// Method implementation for Add Adornments at XY /// </summary> /// <param name="x">The X Value</param> /// <param name="y">The Y Value</param> /// <param name="pointindex">The Point Index</param> /// <param name="startDepth">The Start Depth</param> protected virtual void AddAdornmentAtXY(double x, double y, int pointindex, double startDepth) { double adornposX = x, adornposY = y; if (pointindex < Adornments.Count) { Adornments[pointindex].SetData(x, y, adornposX, adornposY); } else { Adornments.Add(this.CreateAdornment(this, x, y, adornposX, adornposY, startDepth)); } }
/// <summary> /// Method implementation for Clear Unused Adornments /// </summary> /// <param name="startIndex">The start index.</param> protected void ClearUnUsedAdornments(int startIndex) { if (Adornments.Count <= startIndex) { return; } var count = Adornments.Count; for (var i = startIndex; i < count; i++) { Adornments.RemoveAt(startIndex); } }
/// <summary> /// To calculate the segments if the pyramid mode is surface /// </summary> private void CalculateSurfaceSegments(double sumValues, int count, double gapHeight, List <double> xValues) { var toggledYValues = YValues.ToList(); if (ToggledLegendIndex.Count > 0) { toggledYValues = GetYValues(); } currY = 0; double[] y = new double[count]; double[] height = new double[count]; double preSum = GetSurfaceHeight(0, sumValues); for (int i = 0; i < count; i++) { y[i] = currY; height[i] = GetSurfaceHeight(currY, Math.Abs(double.IsNaN(toggledYValues[i]) ? 0 : toggledYValues[i])); currY += height[i] + gapHeight * preSum; } double coef = 1 / (currY - gapHeight * preSum); for (int i = 0; i < count; i++) { double currHeight = 0; if (!double.IsNaN(YValues[i])) { currHeight = coef * y[i]; PyramidSegment pyramidSegment = new PyramidSegment(currHeight, coef * height[i], this.ExplodeOffset, this, i == this.ExplodeIndex || this.ExplodeAll ? true : false); pyramidSegment.Item = ActualData[i]; pyramidSegment.XData = xValues[i]; pyramidSegment.YData = Math.Abs(YValues[i]); if (ToggledLegendIndex.Contains(i)) { pyramidSegment.IsSegmentVisible = false; } else { pyramidSegment.IsSegmentVisible = true; } this.Segments.Add(pyramidSegment); if (AdornmentsInfo != null) { Adornments.Add(this.CreateAdornment(this, xValues[i], toggledYValues[i], 0, double.IsNaN(currHeight) ? 1 - height[i] / 2 : currHeight + coef * height[i] / 2)); } } } }
/// <summary> /// Method implementation for Add ColumnAdornments in Chart /// </summary> /// <param name="values"></param> protected virtual void AddColumnAdornments(params double[] values) { ////values[0] --> xData ////values[1] --> yData ////values[2] --> xPos ////values[3] --> yPos ////values[4] --> data point index ////values[5] --> Median value. double adornposX = values[2] + values[5], adornposY = values[3]; int pointIndex = (int)values[4]; if ((EmptyPointIndexes != null && EmptyPointIndexes.Any() && EmptyPointIndexes[0].Contains(pointIndex) && (EmptyPointStyle == Charts.EmptyPointStyle.Symbol || EmptyPointStyle == Charts.EmptyPointStyle.SymbolAndInterior))) { if (this is StackingSeriesBase) { adornposY = (EmptyPointValue == EmptyPointValue.Average) ? values[3] : values[1]; } else { adornposY = values[1]; // WPF-13874-EmptyPoint segment adornmentinfo positioning wrongly when EmptyPointValues is Average } } if (pointIndex < Adornments.Count) { Adornments[pointIndex].SetData(values[0], values[1], adornposX, adornposY); } else { Adornments.Add(CreateAdornment(this, values[0], values[1], adornposX, adornposY)); } if (!(this is HistogramSeries)) { if (ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed && this.GroupedActualData.Count > 0) { Adornments[pointIndex].Item = this.GroupedActualData[pointIndex]; } else { Adornments[pointIndex].Item = ActualData[pointIndex]; } } }
private void AddAdornments(double x, double yValue, int i) { double adornX = 0d, adornY = 0d; adornX = x; adornY = yValue; if (i < Adornments.Count) { Adornments[i].SetData(adornX, adornY, adornX, adornY); } else { Adornments.Add(this.CreateAdornment(this, adornX, adornY, adornX, adornY)); } Adornments[i].Item = ActualData[i]; }
/// <summary> /// Adds the adornment to the adornments collection. /// </summary> /// <param name="xValue">The X Value</param> /// <param name="yValue">The Y Value</param> /// <param name="index">The Index</param> /// <param name="depth">The Depth</param> protected virtual void AddAdornments(double xValue, double yValue, int index, double depth) { double adornX = 0d, adornY = 0d; adornX = xValue; adornY = yValue; if (index < Adornments.Count) { Adornments[index].SetData(adornX, adornY, adornX, adornY, depth); } else { Adornments.Add(this.CreateAdornment(this, adornX, adornY, adornX, adornY, depth)); } Adornments[index].Item = this.ActualData[index]; }
/// <summary> /// Creates the segment of PyramidSeries. /// </summary> public override void CreateSegments() { Adornments.Clear(); this.Segments.Clear(); int count = DataCount; List <double> xValues = GetXValues(); IList <double> toggledYValues = null; if (ToggledLegendIndex.Count > 0) { toggledYValues = GetYValues(); } else { toggledYValues = YValues; } double sumValues = 0; double gapRatio = this.GapRatio; ChartPyramidMode pyramidMode = this.PyramidMode; for (int i = 0; i < count; i++) { sumValues += Math.Max(0, Math.Abs(double.IsNaN(toggledYValues[i]) ? 0 : toggledYValues[i])); } double gapHeight = gapRatio / (count - 1); if (pyramidMode == ChartPyramidMode.Linear) { this.CalculateLinearSegments(sumValues, gapRatio, count, xValues); } else { this.CalculateSurfaceSegments(sumValues, count, gapHeight, xValues); } if (ShowEmptyPoints) { UpdateEmptyPointSegments(xValues, false); } if (ActualArea != null) { ActualArea.IsUpdateLegend = true; } }
/// <summary> /// Called when DataSource property changed /// </summary> /// <param name="oldValue"></param> /// <param name="newValue"></param> protected override void OnDataSourceChanged(System.Collections.IEnumerable oldValue, System.Collections.IEnumerable newValue) { if (AdornmentsInfo != null) { Adornments.Clear(); AdornmentsInfo.UpdateElements(); } base.OnDataSourceChanged(oldValue, newValue); var area = this.Area; if (area != null) { area.IsUpdateLegend = area.HasDataPointBasedLegend(); } }
/// <summary> /// Method implementation for Add Adornments at XY /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="pointindex"></param> protected virtual void AddAdornmentAtXY(double x, double y, int pointindex) { double adornposX = x, adornposY = y; if (pointindex < Adornments.Count) { Adornments[pointindex].SetData(x, y, adornposX, adornposY); } else { Adornments.Add(CreateAdornment(this, x, y, adornposX, adornposY)); } if (pointindex < ActualData.Count) { Adornments[pointindex].Item = ActualData[pointindex]; } }
private void AddDoughnutAdornments(double x, double y, double startAngle, double endAngle, int i, int index) { double angle = (startAngle + endAngle) / 2; if (Area == null || Area.RootPanelDesiredSize == null || Area.RootPanelDesiredSize.Value == null) { return; } var actualheight = Area.RootPanelDesiredSize.Value.Height; var actualwidth = Area.RootPanelDesiredSize.Value.Width; double doughnutIndex = 0d, actualRadius = 0d, remainingWidth = 0, equalParts = 0d, radius = 0d; if (IsStackedDoughnut) { int doughnutSegmentsCount = DataCount; actualRadius = this.InternalDoughnutSize * (Math.Min(actualwidth, actualheight)) / 2; remainingWidth = actualRadius - (actualRadius * ActualArea.InternalDoughnutHoleSize); equalParts = (remainingWidth / doughnutSegmentsCount) * InternalDoughnutCoefficient; // Segments count is not updated so datacount is used. For more safer update in dynamic updates the radius is also updated in the ChartPieAdornment.Update. radius = actualRadius - (equalParts * (doughnutSegmentsCount - (index + 1))); } else { var doughnutSeries = (from series in Area.VisibleSeries where series is DoughnutSeries select series).ToList(); var doughnutSeriesCount = doughnutSeries.Count(); doughnutIndex = doughnutSeries.IndexOf(this); actualRadius = this.InternalDoughnutSize * (Math.Min(actualwidth, actualheight)) / 2; remainingWidth = actualRadius - (actualRadius * Area.InternalDoughnutHoleSize); equalParts = remainingWidth / doughnutSeriesCount; radius = actualRadius - (equalParts * (doughnutSeriesCount - (doughnutIndex + 1))); } if (index < Adornments.Count) { Adornments[index].SetData(x, y, angle, radius); } else { Adornments.Add(this.CreateAdornment(this, x, y, angle, radius)); } Adornments[index].Item = !double.IsNaN(GroupTo) ? Segments[index].Item : ActualData[index]; }
/// <summary> /// Creates the segments of FunnelSeries. /// </summary> public override void CreateSegments() { Segments.Clear(); Adornments.Clear(); List <double> xValues = GetXValues(); double sumValues = 0d, gapRatio = this.GapRatio; int count = DataCount; int explodedIndex = this.ExplodeIndex; ChartFunnelMode funnelmode = this.FunnelMode; IList <double> toggledYValues = null; if (ToggledLegendIndex.Count > 0) { toggledYValues = GetYValues(); } else { toggledYValues = YValues; } for (int i = 0; i < count; i++) { sumValues += Math.Max(0, Math.Abs(double.IsNaN(toggledYValues[i]) ? 0 : toggledYValues[i])); } if (funnelmode == ChartFunnelMode.ValueIsHeight) { this.CalculateValueIsHeightSegments(toggledYValues, xValues, sumValues, gapRatio, count, explodedIndex); } else { this.CalculateValueIsWidthSegments(toggledYValues, xValues, sumValues, gapRatio, count, explodedIndex); } if (ShowEmptyPoints) { UpdateEmptyPointSegments(xValues, false); } if (ActualArea != null) { ActualArea.IsUpdateLegend = true; } }
/// <summary> /// Creates the segments of FastLineBitmapSeries. /// </summary> public override void CreateSegments() { var isGrouped = ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed; if (isGrouped) { xValues = GroupedXValuesIndexes; } else { xValues = (ActualXValues is IList <double>) ? ActualXValues as IList <double> : GetXValues(); } if (isGrouped) { Segments.Clear(); Adornments.Clear(); if (Segment == null || Segments.Count == 0) { FastLineBitmapSegment segment = new FastLineBitmapSegment(xValues, GroupedSeriesYValues[0], this); Segment = segment; Segments.Add(segment); } } else { ClearUnUsedAdornments(this.DataCount); if (Segment == null || Segments.Count == 0) { FastLineBitmapSegment segment = new FastLineBitmapSegment(xValues, YValues, this); Segment = segment; Segments.Add(segment); } else if (ActualXValues != null) { Segment.SetData(xValues, YValues); (Segment as FastLineBitmapSegment).SetRange(); Segment.Item = ActualData; } } isAdornmentPending = true; }
/// <summary> /// Creates the segments of FastScatterBitmapSeries /// </summary> public override void CreateSegments() { bool isGrouping = this.ActualXAxis is CategoryAxis && !(this.ActualXAxis as CategoryAxis).IsIndexed; if (isGrouping) { xValues = GroupedXValuesIndexes; } else { xValues = GetXValues(); } if (isGrouping) { Segments.Clear(); Adornments.Clear(); if (Segments == null || Segments.Count == 0) { Segment = new FastScatterBitmapSegment(xValues, GroupedSeriesYValues[0], this); Segments.Add(Segment); } } else { ClearUnUsedAdornments(this.DataCount); if (Segments == null || Segments.Count == 0) { Segment = new FastScatterBitmapSegment(xValues, YValues, this); Segments.Add(Segment); } else if (ActualXValues != null) { Segment.SetData(xValues, YValues); (Segment as FastScatterBitmapSegment).SetRange(); Segment.Item = ActualData; } } isAdornmentsBending = true; }
/// <summary> /// To calculate the segments if the pyramid mode is linear /// </summary> private void CalculateLinearSegments(double sumValues, double gapRatio, int count, List <double> xValues) { var toggledYValues = YValues.ToList(); if (ToggledLegendIndex.Count > 0) { toggledYValues = GetYValues(); } currY = 0; double coef = 1d / (sumValues * (1 + gapRatio / (1 - gapRatio))); for (int i = 0; i < count; i++) { double height = 0; if (!double.IsNaN(YValues[i])) { height = coef * Math.Abs(double.IsNaN(toggledYValues[i]) ? 0 : toggledYValues[i]); PyramidSegment pyramidSegment = new PyramidSegment(currY, height, this.ExplodeOffset, this, i == ExplodeIndex || this.ExplodeAll ? true : false); pyramidSegment.Item = ActualData[i]; pyramidSegment.XData = xValues[i]; pyramidSegment.YData = Math.Abs(YValues[i]); if (ToggledLegendIndex.Contains(i)) { pyramidSegment.IsSegmentVisible = false; } else { pyramidSegment.IsSegmentVisible = true; } this.Segments.Add(pyramidSegment); currY += (gapRatio / (count - 1)) + height; if (AdornmentsInfo != null) { Adornments.Add(this.CreateAdornment(this, xValues[i], toggledYValues[i], 0, double.IsNaN(currY) ? 1 - height / 2 : currY - height / 2)); Adornments[Segments.Count - 1].Item = ActualData[i]; } } } }
/// <summary> /// To calculate the segments if the pyramid mode is vlaueisHeight. /// </summary> private void CalculateValueIsHeightSegments(IList <double> yValues, List <double> xValues, double sumValues, double gapRatio, int dataCount, int explodedIndex) { currY = 0d; double coefHeight = 1 / sumValues; double spacing = gapRatio / (DataCount - 1); for (int i = DataCount - 1; i >= 0; i--) { double height = 0; if (!double.IsNaN(YValues[i])) { height = Math.Abs(double.IsNaN(yValues[i]) ? 0 : yValues[i]) * coefHeight; FunnelSegment funnelSegment = new FunnelSegment(currY, height, this, explodedIndex == i || this.ExplodeAll ? true : false); funnelSegment.Item = ActualData[i]; // WPF-14426 Funnel series legend and segment colour is changing while setting emptypoint funnelSegment.XData = xValues[i]; funnelSegment.YData = YValues[i]; if (ToggledLegendIndex.Contains(i)) { funnelSegment.IsSegmentVisible = false; } else { funnelSegment.IsSegmentVisible = true; } Segments.Add(funnelSegment); if (AdornmentsInfo != null) { ChartAdornment adornment = (this.CreateAdornment(this, xValues[i], yValues[i], 0, double.IsNaN(currY) ? 0 : currY + (height + spacing) / 2)); adornment.Item = ActualData[i]; Adornments.Add(adornment); } currY += height + spacing; } } }
/// <summary> /// Method implementation for Add AreaAdornments in ChartAdornments /// </summary> /// <param name="values"></param> protected virtual void AddAreaAdornments(params IList <double>[] values) { IList <double> yValues = values[0]; List <double> xValues = new List <double>(); if (ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed) { xValues = GroupedXValuesIndexes; } else { xValues = GetXValues(); } if (values.Length == 1) { int i; for (i = 0; i < DataCount; i++) { if (i < xValues.Count && i < yValues.Count) { double adornX = xValues[i]; double adornY = yValues[i]; if (i < Adornments.Count) { Adornments[i].SetData(xValues[i], yValues[i], adornX, adornY); } else { Adornments.Add(CreateAdornment(this, xValues[i], yValues[i], adornX, adornY)); } Adornments[i].Item = ActualData[i]; } } } }
/// <summary> /// Creates the segments of ColumnSeries. /// </summary> public override void CreateSegments() { double x1, x2, y1, y2; var isGrouped = ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed; List <double> xValues = null; if (isGrouped) { xValues = GroupedXValuesIndexes; } else { xValues = GetXValues(); } double median = 0d; double origin = ActualXAxis != null ? ActualXAxis.Origin : 0; if (ActualXAxis != null && ActualXAxis.Origin == 0 && ActualYAxis is LogarithmicAxis && (ActualYAxis as LogarithmicAxis).Minimum != null) { origin = (double)(ActualYAxis as LogarithmicAxis).Minimum; } if (xValues != null) { DoubleRange sbsInfo = this.GetSideBySideInfo(this); median = sbsInfo.Delta / 2; int segmentCount = 0; if (isGrouped) { Segments.Clear(); Adornments.Clear(); GroupedActualData.Clear(); for (int i = 0; i < DistinctValuesIndexes.Count; i++) { var list = (from index in DistinctValuesIndexes[i] where GroupedSeriesYValues[0].Count > index select new List <double> { GroupedSeriesYValues[0][index], index }). OrderByDescending(val => val[0]).ToList(); for (int j = 0; j < list.Count; j++) { var yValue = list[j][0]; x1 = i + sbsInfo.Start; x2 = i + sbsInfo.End; y1 = yValue; y2 = origin; // Setting origin value for column segment GroupedActualData.Add(ActualData[(int)list[j][1]]); Segments.Add(new ColumnSegment(x1, y1, x2, y2, this) { XData = xValues[j], YData = yValue, Item = GroupedActualData[segmentCount] }); if (AdornmentsInfo != null) { if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Top) { AddColumnAdornments(i, yValue, x1, y1, segmentCount, median); } else if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Bottom) { AddColumnAdornments(i, yValue, x1, y2, segmentCount, median); } else { AddColumnAdornments(i, yValue, x1, y1 + (y2 - y1) / 2, segmentCount, median); } } segmentCount++; } } } else { ClearUnUsedSegments(this.DataCount); ClearUnUsedAdornments(this.DataCount); double start = sbsInfo.Start; double end = sbsInfo.End; List <int> SeriesCount = new List <int>(); foreach (ChartSeriesBase series in Area.Series) { SeriesCount.Add(series.DataCount); } for (int i = 0; i < this.DataCount; i++) { if (i < this.DataCount) { x1 = xValues[i] + start; x2 = xValues[i] + end; y1 = YValues[i]; y2 = origin; // Setting origin value for column segment if (i < Segments.Count) { (Segments[i]).SetData(x1, y1, x2, y2); (Segments[i] as ColumnSegment).XData = xValues[i]; (Segments[i] as ColumnSegment).YData = YValues[i]; (Segments[i] as ColumnSegment).Item = ActualData[i]; if (SegmentColorPath != null && !Segments[i].IsEmptySegmentInterior && ColorValues.Count > 0 && !Segments[i].IsSelectedSegment) { Segments[i].Interior = (Interior != null) ? Interior : ColorValues[i]; } } else { Segments.Add(new ColumnSegment(x1, y1, x2, y2, this) { XData = xValues[i], YData = YValues[i], Item = ActualData[i] }); } if (AdornmentsInfo != null) { if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Top) { AddColumnAdornments(xValues[i], YValues[i], x1, y1, i, median); } else if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Bottom) { AddColumnAdornments(xValues[i], YValues[i], x1, y2, i, median); } else { AddColumnAdornments(xValues[i], YValues[i], x1, y1 + (y2 - y1) / 2, i, median); } } } } if (ShowEmptyPoints) { UpdateEmptyPointSegments(xValues, true); } } } }
protected override void OnVisibleRangeChanged(VisibleRangeChangedEventArgs e) { if (AdornmentsInfo != null && isAdornmentPending) { List <double> xValues = null; var isGrouped = ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed; if (isGrouped) { xValues = GroupedXValuesIndexes; } else { xValues = GetXValues(); } if (xValues != null && ActualXAxis != null && !ActualXAxis.VisibleRange.IsEmpty) { double xBase = ActualXAxis.IsLogarithmic ? (ActualXAxis as LogarithmicAxis).LogarithmicBase : 1; double start = ActualXAxis.VisibleRange.Start; double end = ActualXAxis.VisibleRange.End; if (isGrouped) { for (int i = 0; i < xValues.Count; i++) { if (i < xValues.Count) { double x = xValues[i]; double actualX = ActualXAxis.IsLogarithmic ? Math.Log(x, xBase) : x; if (actualX >= start && actualX <= end) { double y = GroupedSeriesYValues[0][i]; if (i < Adornments.Count) { Adornments[i].SetData(x, y, x, y); } else { Adornments.Add(this.CreateAdornment(this, x, y, x, y)); } Adornments[i].Item = ActualData[i]; } } } } else { for (int i = 0; i < DataCount; i++) { double x = xValues[i]; double actualX = ActualXAxis.IsLogarithmic ? Math.Log(x, xBase) : x; if (actualX >= start && actualX <= end) { double y = YValues[i]; if (i < Adornments.Count) { Adornments[i].SetData(x, y, x, y); } else { Adornments.Add(this.CreateAdornment(this, x, y, x, y)); } Adornments[i].Item = ActualData[i]; } } } } isAdornmentPending = false; } }
/// <summary> /// Creates the segments of FastBarBitmapSeries /// </summary> public override void CreateSegments() { var isGrouped = (ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed); if (isGrouped) { xValues = GroupedXValuesIndexes; } else { xValues = GetXValues(); } IList <double> x1Values, x2Values, y1Values, y2Values; x1Values = new List <double>(); x2Values = new List <double>(); y1Values = new List <double>(); y2Values = new List <double>(); if (xValues != null) { DoubleRange sbsInfo = this.GetSideBySideInfo(this); double origin = ActualXAxis != null ? ActualXAxis.Origin : 0; if (ActualXAxis != null && ActualXAxis.Origin == 0 && ActualYAxis is LogarithmicAxis && (ActualYAxis as LogarithmicAxis).Minimum != null) { origin = (double)(ActualYAxis as LogarithmicAxis).Minimum; } if (isGrouped) { Segments.Clear(); Adornments.Clear(); GroupedActualData.Clear(); for (int i = 0; i < DistinctValuesIndexes.Count; i++) { var list = (from index in DistinctValuesIndexes[i] where GroupedSeriesYValues[0].Count > index select new List <double> { GroupedSeriesYValues[0][index], index }). OrderByDescending(val => val[0]).ToList(); for (int j = 0; j < list.Count; j++) { var yValue = list[j][0]; GroupedActualData.Add(ActualData[(int)list[j][1]]); if (i < xValues.Count && GroupedSeriesYValues[0].Count > i) { x1Values.Add(i + sbsInfo.Start); x2Values.Add(i + sbsInfo.End); y1Values.Add(yValue); y2Values.Add(ActualXAxis != null ? ActualXAxis.Origin : 0); // Setting origin value for fastbar segment } } } if (Segment != null && (!IsActualTransposed && Segment is FastBarBitmapSegment) || (IsActualTransposed && Segment is FastColumnBitmapSegment)) { Segments.Clear(); } if (Segment == null || Segments.Count == 0) { if (IsActualTransposed) { Segment = new FastBarBitmapSegment(x1Values, y1Values, x2Values, y2Values, this); } else { Segment = new FastColumnBitmapSegment(x1Values, y1Values, x2Values, y2Values, this); } Segment.SetData(x1Values, y1Values, x2Values, y2Values); this.Segments.Add(Segment); } if (AdornmentsInfo != null) { int count = 0; for (int i = 0; i < DistinctValuesIndexes.Count; i++) { var list = (from index in DistinctValuesIndexes[i] select new List <double> { GroupedSeriesYValues[0][index], index }). OrderByDescending(val => val[0]).ToList(); for (int j = 0; j < DistinctValuesIndexes[i].Count; j++) { var yValue = list[j][0]; if (i < xValues.Count) { if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Top) { AddColumnAdornments(i, yValue, x1Values[count], y1Values[count], count, sbsInfo.Delta / 2); } else if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Bottom) { AddColumnAdornments(i, yValue, x1Values[count], y2Values[count], count, sbsInfo.Delta / 2); } else { AddColumnAdornments(i, yValue, x1Values[count], y1Values[count] + (y2Values[count] - y1Values[count]) / 2, count, sbsInfo.Delta / 2); } } count++; } } } } else { if (!this.IsIndexed) { for (int i = 0; i < this.DataCount; i++) { x1Values.Add(xValues[i] + sbsInfo.Start); x2Values.Add(xValues[i] + sbsInfo.End); y1Values.Add(YValues[i]); y2Values.Add(ActualXAxis != null ? ActualXAxis.Origin : 0); // Setting origin value for fastbar segment } } else { for (int i = 0; i < this.DataCount; i++) { x1Values.Add(i + sbsInfo.Start); x2Values.Add(i + sbsInfo.End); y1Values.Add(YValues[i]); y2Values.Add(origin); } } if (Segment != null && (!IsActualTransposed && Segment is FastBarBitmapSegment) || (IsActualTransposed && Segment is FastColumnBitmapSegment)) { Segments.Clear(); } if (Segment == null || Segments.Count == 0) { if (IsActualTransposed) { Segment = new FastBarBitmapSegment(x1Values, y1Values, x2Values, y2Values, this); } else { Segment = new FastColumnBitmapSegment(x1Values, y1Values, x2Values, y2Values, this); } Segment.SetData(x1Values, y1Values, x2Values, y2Values); this.Segments.Add(Segment); } if (Segment is FastBarBitmapSegment) { (Segment as FastBarBitmapSegment).Item = ActualData; (Segment as FastBarBitmapSegment).SetData(x1Values, y1Values, x2Values, y2Values); } else { (Segment as FastColumnBitmapSegment).Item = ActualData; (Segment as FastColumnBitmapSegment).SetData(x1Values, y1Values, x2Values, y2Values); } if (AdornmentsInfo != null) { ClearUnUsedAdornments(this.DataCount); for (int i = 0; i < this.DataCount; i++) { if (i < this.DataCount) { if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Top) { AddColumnAdornments(xValues[i], YValues[i], x1Values[i], y1Values[i], i, sbsInfo.Delta / 2); } else if (this.AdornmentsInfo.AdornmentsPosition == AdornmentsPosition.Bottom) { AddColumnAdornments(xValues[i], YValues[i], x1Values[i], y2Values[i], i, sbsInfo.Delta / 2); } else { AddColumnAdornments(xValues[i], YValues[i], x1Values[i], y1Values[i] + (y2Values[i] - y1Values[i]) / 2, i, sbsInfo.Delta / 2); } } } } } } }
/// <summary> /// Creates the segments of StepAreaSeries. /// </summary> public override void CreateSegments() { List <double> xValues = null; bool isGrouping = this.ActualXAxis is CategoryAxis && !(this.ActualXAxis as CategoryAxis).IsIndexed; if (isGrouping) { xValues = GroupedXValuesIndexes; } else { xValues = GetXValues(); } if (xValues.Count == 0) { return; } double Origin = this.ActualXAxis.Origin; if (ActualXAxis != null && ActualXAxis.Origin == 0 && ActualYAxis is LogarithmicAxis && (ActualYAxis as LogarithmicAxis).Minimum != null) { Origin = (double)(ActualYAxis as LogarithmicAxis).Minimum; } double xOffset = 0d; if (ActualXAxis is CategoryAxis && (ActualXAxis as CategoryAxis).LabelPlacement == LabelPlacement.BetweenTicks) { xOffset = 0.5d; } if (isGrouping) { Segments.Clear(); Adornments.Clear(); var stepAreaPoints = new List <ChartPoint> { new ChartPoint((xValues[xValues.Count - 1] + xOffset), Origin), new ChartPoint(xValues[0] - xOffset, Origin) }; for (int i = 0; i < xValues.Count; i++) { stepAreaPoints.Add(new ChartPoint(xValues[i] - xOffset, GroupedSeriesYValues[0][i])); if (i != xValues.Count - 1) { stepAreaPoints.Add(new ChartPoint(xValues[i + 1] - xOffset, GroupedSeriesYValues[0][i])); } } if (xOffset > 0) { stepAreaPoints.Add(new ChartPoint((xValues[xValues.Count - 1]) + xOffset, GroupedSeriesYValues[0][xValues.Count - 1])); } if (Segments.Count == 0) { var segment = new StepAreaSegment(stepAreaPoints, this) { Series = this, Item = ActualData, XRange = DoubleRange.Empty, YRange = DoubleRange.Empty }; segment.SetData(stepAreaPoints); Segments.Add(segment); } if (AdornmentsInfo != null) { AddAreaAdornments(GroupedSeriesYValues[0]); } } else { ClearUnUsedAdornments(DataCount); var stepAreaPoints = new List <ChartPoint> { new ChartPoint((xValues[DataCount - 1] + xOffset), Origin), new ChartPoint(xValues[0] - xOffset, Origin) }; for (int i = 0; i < DataCount; i++) { stepAreaPoints.Add(new ChartPoint(xValues[i] - xOffset, YValues[i])); if (i != DataCount - 1) { stepAreaPoints.Add(new ChartPoint(xValues[i + 1] - xOffset, YValues[i])); } } if (xOffset > 0) { stepAreaPoints.Add(new ChartPoint((xValues[DataCount - 1]) + xOffset, YValues[DataCount - 1])); } if (Segments.Count == 0) { var segment = new StepAreaSegment(stepAreaPoints, this) { Series = this, Item = ActualData, XRange = DoubleRange.Empty, YRange = DoubleRange.Empty }; segment.SetData(stepAreaPoints); Segments.Add(segment); } else { Segments[0].Item = ActualData; Segments[0].SetData(stepAreaPoints); } if (AdornmentsInfo != null) { AddAreaAdornments(YValues); } } }
/// <summary> /// Creates the segments of StackingAreaSeries /// </summary> public override void CreateSegments() { ClearUnUsedAdornments(this.DataCount); List <double> xValues = new List <double>(); List <double> drawingListXValues = new List <double>(); List <double> drawingListYValues = new List <double>(); double Origin = ActualXAxis != null ? ActualXAxis.Origin : 0d; if (ActualXAxis != null && ActualXAxis.Origin == 0 && ActualYAxis is LogarithmicAxis && (ActualYAxis as LogarithmicAxis).Minimum != null) { Origin = (double)(ActualYAxis as LogarithmicAxis).Minimum; } if (ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed) { Adornments.Clear(); xValues = GroupedXValuesIndexes; } else { xValues = GetXValues(); } var stackingValues = GetCumulativeStackValues(this); if (stackingValues != null) { YRangeStartValues = stackingValues.StartValues; YRangeEndValues = stackingValues.EndValues; if (YRangeStartValues != null) { drawingListXValues.AddRange(xValues); drawingListYValues.AddRange(YRangeStartValues); } else { drawingListXValues.AddRange(xValues); drawingListYValues = (from val in xValues select Origin).ToList(); } drawingListXValues.AddRange((from val in xValues select val).Reverse().ToList()); drawingListYValues.AddRange((from val in YRangeEndValues select val).Reverse().ToList()); if (Segment == null || Segments.Count == 0) { Segment = new StackingAreaSegment(drawingListXValues, drawingListYValues, this) { Series = this, Item = ActualData }; Segment.SetData(drawingListXValues, drawingListYValues); Segments.Add(Segment); } else { Segment.Item = ActualData; Segment.SetData(drawingListXValues, drawingListYValues); } if (ShowEmptyPoints) { UpdateEmptyPointSegments(drawingListXValues, false); } if (AdornmentsInfo != null) { AddStackingAreaAdornments(YRangeEndValues); } } }