/// <summary> /// Render all the <see cref="CurveItem"/> objects in the list to the /// specified <see cref="Graphics"/> /// device by calling the <see cref="CurveItem.Draw"/> member function of /// each <see cref="CurveItem"/> object. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void Draw(Graphics g, GraphPane pane, float scaleFactor) { // Configure the accumulator for stacked bars //Bar.ResetBarStack(); // Count the number of BarItems in the curvelist int pos = NumBars; // sorted overlay bars are a special case, since they are sorted independently at each // ordinal position. if (pane._barSettings.Type == BarType.SortedOverlay) { // First, create a new curveList with references (not clones) of the curves var tempList = new CurveList(); tempList.AddRange(this.Where(curve => curve.IsBar)); // Loop through the bars, graphing each ordinal position separately for (var i = 0; i < MaxPts; i++) { // At each ordinal position, sort the curves according to the value axis value tempList.Sort(pane._barSettings.Base == BarBase.X ? SortType.YValues : SortType.XValues, i); // plot the bars for the current ordinal position, in sorted order foreach (var barItem in tempList.Cast <BarItem>()) { barItem.Bar.DrawSingleBar(g, pane, barItem, barItem.BaseAxis(pane), barItem.ValueAxis(pane), 0, i, barItem.GetBarWidth(pane), scaleFactor); } } } var list = this.Where(c => !(c.IsBar && pane._barSettings.Type == BarType.SortedOverlay)); // Loop over the remaining curves first drawing the ones that have ZOrder set. // The list is already sorted respecting curves' ZOrder. foreach (var curve in list.Where(c => c.ZOrder >= 0)) { if (curve.IsBar) { pos--; } // if it's a sorted overlay bar type, it's already been done above curve.Draw(g, pane, pos, scaleFactor); } // Loop for each curve in reverse order to pick up the remaining curves. // The reverse order is done so that curves that are later in the list are plotted behind // curves that are earlier in the list. foreach (var curve in list.Where(c => c.ZOrder < 0).Reverse()) { if (curve.IsBar) { pos--; } // Render the curve // if it's a sorted overlay bar type, it's already been done above curve.Draw(g, pane, pos, scaleFactor); } }
/// <summary> /// Render all the <see cref="CurveItem"/> objects in the list to the /// specified <see cref="Graphics"/> /// device by calling the <see cref="CurveItem.Draw"/> member function of /// each <see cref="CurveItem"/> object. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void Draw(Graphics g, GraphPane pane, float scaleFactor) { // Configure the accumulator for stacked bars //Bar.ResetBarStack(); // Count the number of BarItems in the curvelist int pos = this.NumBars; // sorted overlay bars are a special case, since they are sorted independently at each // ordinal position. if (pane._barSettings.Type == BarType.SortedOverlay) { // First, create a new curveList with references (not clones) of the curves CurveList tempList = new CurveList(); foreach (CurveItem curve in this) { if (curve.IsBar) { tempList.Add((CurveItem)curve); } } // Loop through the bars, graphing each ordinal position separately for (int i = 0; i < this.maxPts; i++) { // At each ordinal position, sort the curves according to the value axis value tempList.Sort(pane._barSettings.Base == BarBase.X ? SortType.YValues : SortType.XValues, i); var list = tempList.Cast <BarItem>().OrderByDescending(b => b.SortedOverlayPriority); // plot the bars for the current ordinal position, in sorted order foreach (BarItem barItem in list) { barItem.Bar.DrawSingleBar(g, pane, barItem, ((BarItem)barItem).BaseAxis(pane), ((BarItem)barItem).ValueAxis(pane), 0, i, ((BarItem)barItem).GetBarWidth(pane), scaleFactor); } } } // Loop for each curve in reverse order to pick up the remaining curves // The reverse order is done so that curves that are later in the list are plotted behind // curves that are earlier in the list for (int i = this.Count - 1; i >= 0; i--) { CurveItem curve = this[i]; if (curve.IsBar) { pos--; } // Render the curve // if it's a sorted overlay bar type, it's already been done above if (!(curve.IsBar && pane._barSettings.Type == BarType.SortedOverlay)) { curve.Draw(g, pane, pos, scaleFactor); } } }