/// <summary> /// Determine the coords for the rectangle associated with a specified point for this <see cref="CurveItem"/> /// </summary> /// <param name="pane"> /// The <see cref="GraphPane"/> to which this curve belongs /// </param> /// <param name="i"> /// The index of the point of interest /// </param> /// <param name="coords"> /// A list of coordinates that represents the "rect" for this point (used in an html AREA tag) /// </param> /// <returns> /// true if it's a valid point, false otherwise /// </returns> public override bool GetCoords(GraphPane pane, int i, out string coords) { coords = string.Empty; if (i < 0 || i >= this._points.Count) { return false; } PointPair pt = this._points[i]; if (pt.IsInvalid) { return false; } double x, y, z; ValueHandler valueHandler = new ValueHandler(pane, false); valueHandler.GetValues(this, i, out x, out z, out y); Axis yAxis = this.GetYAxis(pane); Axis xAxis = this.GetXAxis(pane); PointF pixPt = new PointF(xAxis.Scale.Transform(this._isOverrideOrdinal, i, x), yAxis.Scale.Transform(this._isOverrideOrdinal, i, y)); if (!pane.Chart.Rect.Contains(pixPt)) { return false; } float halfSize = this._symbol.Size * pane.CalcScaleFactor(); coords = string.Format("{0:f0},{1:f0},{2:f0},{3:f0}", pixPt.X - halfSize, pixPt.Y - halfSize, pixPt.X + halfSize, pixPt.Y + halfSize); return true; }
/// <summary> /// Determine the coords for the rectangle associated with a specified point for this <see cref="CurveItem"/> /// </summary> /// <param name="pane"> /// The <see cref="GraphPane"/> to which this curve belongs /// </param> /// <param name="i"> /// The index of the point of interest /// </param> /// <param name="coords"> /// A list of coordinates that represents the "rect" for this point (used in an html AREA tag) /// </param> /// <returns> /// true if it's a valid point, false otherwise /// </returns> public override bool GetCoords(GraphPane pane, int i, out string coords) { coords = string.Empty; if (i < 0 || i >= this._points.Count) { return false; } Axis valueAxis = this.ValueAxis(pane); Axis baseAxis = this.BaseAxis(pane); float scaledSize = this._bar.Symbol.Size * pane.CalcScaleFactor(); // pixBase = pixel value for the bar center on the base axis // pixHiVal = pixel value for the bar top on the value axis // pixLowVal = pixel value for the bar bottom on the value axis float pixBase, pixHiVal, pixLowVal; float clusterWidth = pane.BarSettings.GetClusterWidth(); float barWidth = this.GetBarWidth(pane); float clusterGap = pane._barSettings.MinClusterGap * barWidth; float barGap = barWidth * pane._barSettings.MinBarGap; // curBase = the scale value on the base axis of the current bar // curHiVal = the scale value on the value axis of the current bar // curLowVal = the scale value of the bottom of the bar double curBase, curLowVal, curHiVal; ValueHandler valueHandler = new ValueHandler(pane, false); valueHandler.GetValues(this, i, out curBase, out curLowVal, out curHiVal); // Any value set to double max is invalid and should be skipped // This is used for calculated values that are out of range, divide // by zero, etc. // Also, any value <= zero on a log scale is invalid if (!this._points[i].IsInvalid3D) { // calculate a pixel value for the top of the bar on value axis pixLowVal = valueAxis.Scale.Transform(this._isOverrideOrdinal, i, curLowVal); pixHiVal = valueAxis.Scale.Transform(this._isOverrideOrdinal, i, curHiVal); // calculate a pixel value for the center of the bar on the base axis pixBase = baseAxis.Scale.Transform(this._isOverrideOrdinal, i, curBase); // Calculate the pixel location for the side of the bar (on the base axis) float pixSide = pixBase - scaledSize / 2.0F; // Draw the bar if (baseAxis is XAxis || baseAxis is X2Axis) { coords = string.Format("{0:f0},{1:f0},{2:f0},{3:f0}", pixSide, pixLowVal, pixSide + scaledSize, pixHiVal); } else { coords = string.Format("{0:f0},{1:f0},{2:f0},{3:f0}", pixLowVal, pixSide, pixHiVal, pixSide + scaledSize); } return true; } return false; }
/// <summary> /// Calculate the width of each bar, depending on the actual bar type /// </summary> /// <param name="pane"> /// The pane. /// </param> /// <returns> /// The width for an individual bar, in pixel units /// </returns> public float GetBarWidth(GraphPane pane) { // Total axis width = // npts * ( nbars * ( bar + bargap ) - bargap + clustgap ) // cg * bar = cluster gap // npts = max number of points in any curve // nbars = total number of curves that are of type IsBar // bar = bar width // bg * bar = bar gap // therefore: // totwidth = npts * ( nbars * (bar + bg*bar) - bg*bar + cg*bar ) // totwidth = bar * ( npts * ( nbars * ( 1 + bg ) - bg + cg ) ) // solve for bar float barWidth; if (this is ErrorBarItem) { barWidth = ((ErrorBarItem)this).Bar.Symbol.Size * pane.CalcScaleFactor(); } // else if ( this is HiLowBarItem && pane._barSettings.Type != BarType.ClusterHiLow ) // barWidth = (float) ( ((HiLowBarItem)this).Bar.GetBarWidth( pane, // ((HiLowBarItem)this).BaseAxis(pane), pane.CalcScaleFactor() ) ); // barWidth = (float) ( ((HiLowBarItem)this).Bar.Size * // pane.CalcScaleFactor() ); else { // BarItem or LineItem // For stacked bar types, the bar width will be based on a single bar float numBars = 1.0F; if (pane._barSettings.Type == BarType.Cluster) { numBars = pane.CurveList.NumClusterableBars; } float denom = numBars * (1.0F + pane._barSettings.MinBarGap) - pane._barSettings.MinBarGap + pane._barSettings.MinClusterGap; if (denom <= 0) { denom = 1; } barWidth = pane.BarSettings.GetClusterWidth() / denom; } if (barWidth <= 0) { return 1; } return barWidth; }
/// <summary> /// Determine the coords for the rectangle associated with a specified point for this <see cref="CurveItem"/> /// </summary> /// <param name="pane"> /// The <see cref="GraphPane"/> to which this curve belongs /// </param> /// <param name="i"> /// The index of the point of interest /// </param> /// <param name="coords"> /// A list of coordinates that represents the "rect" for this point (used in an html AREA tag) /// </param> /// <returns> /// true if it's a valid point, false otherwise /// </returns> public override bool GetCoords(GraphPane pane, int i, out string coords) { coords = string.Empty; if (i < 0 || i >= this._points.Count) { return false; } Axis valueAxis = this.ValueAxis(pane); Axis baseAxis = this.BaseAxis(pane); float halfSize = this._bar.Size * pane.CalcScaleFactor(); PointPair pt = this._points[i]; double date = pt.X; double high = pt.Y; double low = pt.Z; if (!pt.IsInvalid3D && (date > 0 || !baseAxis._scale.IsLog) && ((high > 0 && low > 0) || !valueAxis._scale.IsLog)) { float pixBase, pixHigh, pixLow; pixBase = baseAxis.Scale.Transform(this._isOverrideOrdinal, i, date); pixHigh = valueAxis.Scale.Transform(this._isOverrideOrdinal, i, high); pixLow = valueAxis.Scale.Transform(this._isOverrideOrdinal, i, low); // Calculate the pixel location for the side of the bar (on the base axis) float pixSide = pixBase - halfSize; // Draw the bar if (baseAxis is XAxis || baseAxis is X2Axis) { coords = string.Format("{0:f0},{1:f0},{2:f0},{3:f0}", pixSide, pixLow, pixSide + halfSize * 2, pixHigh); } else { coords = string.Format("{0:f0},{1:f0},{2:f0},{3:f0}", pixLow, pixSide, pixHigh, pixSide + halfSize * 2); } return true; } return false; }