/// <summary> /// Basic constructor that saves a reference to the parent /// <see c_ref="GraphPane"/> object. /// </summary> /// <param name="pane">The parent <see c_ref="GraphPane"/> object.</param> /// <param name="initialize">A <see c_ref="bool"/> flag to indicate whether or /// not the drawing variables should be initialized. Initialization is not /// required if this is part of a ZedGraph internal draw operation (i.e., its in /// the middle of a call to <see c_ref="GraphPane.Draw"/>). Otherwise, you should /// initialize to make sure the drawing variables are configured. true to do /// an initialization, false otherwise.</param> public ValueHandler( GraphPane pane, bool initialize ) { _pane = pane; if ( initialize ) { // just create a dummy image, which results in a full draw operation using ( Image image = pane.GetImage() ) { } } }
private void ApplyToAllPanes( GraphPane primaryPane ) { foreach ( GraphPane pane in _masterPane._paneList ) { if ( pane != primaryPane ) { if ( _isSynchronizeXAxes ) Synchronize( primaryPane.XAxis, pane.XAxis ); if ( _isSynchronizeYAxes ) Synchronize( primaryPane.YAxis, pane.YAxis ); } } }
/// <summary> /// Restore the states of the GraphPanes to a previously saved condition (via /// <see c_ref="ZoomStateSave" />. This is essentially an "undo" for live /// pan and scroll actions. Restores a single /// (<see paramref="primaryPane" />) GraphPane if the panes are not synchronized /// (see <see c_ref="IsSynchronizeXAxes" /> and <see c_ref="IsSynchronizeYAxes" />), /// or save a list of states for all GraphPanes if the panes are synchronized. /// </summary> /// <param name="primaryPane">The primary GraphPane on which zoom/pan/scroll operations /// are taking place</param> private void ZoomStateRestore( GraphPane primaryPane ) { if ( _isSynchronizeXAxes || _isSynchronizeYAxes ) { for ( int i = 0; i < _masterPane._paneList.Count; i++ ) { if ( i < _zoomStateStack.Count ) _zoomStateStack[i].ApplyState( _masterPane._paneList[i] ); } } else if ( _zoomState != null ) _zoomState.ApplyState( primaryPane ); ZoomStateClear(); }
/// <summary> /// Protected internal routine that draws the specified single bar (an individual "point") /// of this series to the specified <see c_ref="Graphics"/> device. /// </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 c_ref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see c_ref="CurveItem"/> object representing the /// <see c_ref="Bar"/>'s to be drawn.</param> /// <param name="index"> /// The zero-based index number for the single bar to be drawn. /// </param> /// <param name="pos"> /// The ordinal position of the this bar series (0=first bar, 1=second bar, etc.) /// in the cluster of bars. /// </param> /// <param name="baseAxis">The <see c_ref="Axis"/> class instance that defines the base (independent) /// axis for the <see c_ref="Bar"/></param> /// <param name="valueAxis">The <see c_ref="Axis"/> class instance that defines the value (dependent) /// axis for the <see c_ref="Bar"/></param> /// <param name="barWidth"> /// The width of each bar, in pixels. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see c_ref="GraphPane"/> object using the /// <see c_ref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> virtual protected void DrawSingleBar( Graphics g, GraphPane pane, CurveItem curve, int index, int pos, Axis baseAxis, Axis valueAxis, float barWidth, float scaleFactor ) { // 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 = curve.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( curve, index, 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 ( !curve.Points[index].IsInvalid ) { // calculate a pixel value for the top of the bar on value axis pixLowVal = valueAxis.Scale.Transform( curve.IsOverrideOrdinal, index, curLowVal ); pixHiVal = valueAxis.Scale.Transform( curve.IsOverrideOrdinal, index, curHiVal ); // calculate a pixel value for the center of the bar on the base axis pixBase = baseAxis.Scale.Transform( curve.IsOverrideOrdinal, index, curBase ); // Calculate the pixel location for the side of the bar (on the base axis) float pixSide = pixBase - clusterWidth / 2.0F + clusterGap / 2.0F + pos * ( barWidth + barGap ); // Draw the bar if ( pane._barSettings.Base == BarBase.X ) Draw( g, pane, pixSide, pixSide + barWidth, pixLowVal, pixHiVal, scaleFactor, true, curve.IsSelected, curve.Points[index] ); else Draw( g, pane, pixLowVal, pixHiVal, pixSide, pixSide + barWidth, scaleFactor, true, curve.IsSelected, curve.Points[index] ); } }
/// <summary> /// Save the current states of the GraphPanes to a separate collection. Save a single /// (<see paramref="primaryPane" />) GraphPane if the panes are not synchronized /// (see <see c_ref="IsSynchronizeXAxes" /> and <see c_ref="IsSynchronizeYAxes" />), /// or save a list of states for all GraphPanes if the panes are synchronized. /// </summary> /// <param name="primaryPane">The primary GraphPane on which zoom/pan/scroll operations /// are taking place</param> /// <param name="type">The <see c_ref="ZoomState.StateType" /> that describes the /// current operation</param> /// <returns>The <see c_ref="ZoomState" /> that corresponds to the /// <see paramref="primaryPane" />. /// </returns> private ZoomState ZoomStateSave( GraphPane primaryPane, ZoomState.StateType type ) { ZoomStateClear(); if ( _isSynchronizeXAxes || _isSynchronizeYAxes ) { foreach ( GraphPane pane in _masterPane._paneList ) { ZoomState state = new ZoomState( pane, type ); if ( pane == primaryPane ) _zoomState = state; _zoomStateStack.Add( state ); } } else _zoomState = new ZoomState( primaryPane, type ); return _zoomState; }
/// <summary> /// Make a value label for an <see c_ref="AxisType.Date" /> <see c_ref="Axis" />. /// </summary> /// <param name="pane"> /// A reference to the <see c_ref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="index"> /// The zero-based, ordinal index of the label to be generated. For example, a value of 2 would /// cause the third value label on the axis to be generated. /// </param> /// <param name="dVal"> /// The numeric value associated with the label. This value is ignored for log (<see c_ref="Scale.IsLog"/>) /// and text (<see c_ref="Scale.IsText"/>) type axes. /// </param> /// <returns>The resulting value label as a <see c_ref="string" /></returns> override internal string MakeLabel( GraphPane pane, int index, double dVal ) { if ( _format == null ) _format = Default.Format; return XDate.ToString( dVal, _format ); }
/// <summary> /// Make a value label for an <see c_ref="AxisType.LinearAsOrdinal" /> <see c_ref="Axis" />. /// </summary> /// <param name="pane"> /// A reference to the <see c_ref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="index"> /// The zero-based, ordinal index of the label to be generated. For example, a value of 2 would /// cause the third value label on the axis to be generated. /// </param> /// <param name="dVal"> /// The numeric value associated with the label. This value is ignored for log (<see c_ref="Scale.IsLog"/>) /// and text (<see c_ref="Scale.IsText"/>) type axes. /// </param> /// <returns>The resulting value label as a <see c_ref="string" /></returns> override internal string MakeLabel( GraphPane pane, int index, double dVal ) { if ( _format == null ) _format = Default.Format; double val; int tmpIndex = (int) dVal - 1; if ( pane.CurveList.Count > 0 && pane.CurveList[0].Points.Count > tmpIndex ) { val = pane.CurveList[0].Points[tmpIndex].X; double scaleMult = Math.Pow( 10.0, _mag ); return ( val / scaleMult ).ToString( _format ); } return string.Empty; }
/// <summary> /// Determines if this <see c_ref="Axis" /> object is a "primary" one. /// </summary> /// <remarks> /// The primary axes are the <see c_ref="XAxis" /> (always), the first /// <see c_ref="YAxis" /> in the <see c_ref="GraphPane.YAxisList" /> /// (<see c_ref="CurveItem.YAxisIndex" /> = 0), and the first /// <see c_ref="Y2Axis" /> in the <see c_ref="GraphPane.Y2AxisList" /> /// (<see c_ref="CurveItem.YAxisIndex" /> = 0). Note that /// <see c_ref="GraphPane.YAxis" /> and <see c_ref="GraphPane.Y2Axis" /> /// always reference the primary axes. /// </remarks> /// <param name="pane"> /// A reference to the <see c_ref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <returns>true for a primary <see c_ref="Axis" /> (for the <see c_ref="XAxis" />, /// this is always true), false otherwise</returns> override internal bool IsPrimary( GraphPane pane ) { return this == pane.XAxis; }
/* override internal bool IsCrossed( GraphPane pane ) { return !this.crossAuto && this.cross > pane.YAxis.Min && this.cross < pane.YAxis.Max; } */ /// <summary> /// Gets the "Cross" axis that corresponds to this axis. /// </summary> /// <remarks> /// The cross axis is the axis which determines the of this Axis when the /// <see c_ref="Axis.Cross" >Axis.Cross</see> property is used. The /// cross axis for any <see c_ref="XAxis" /> or <see c_ref="X2Axis" /> /// is always the primary <see c_ref="YAxis" />, and /// the cross axis for any <see c_ref="YAxis" /> or <see c_ref="Y2Axis" /> is /// always the primary <see c_ref="XAxis" />. /// </remarks> /// <param name="pane"> /// A reference to the <see c_ref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> override public Axis GetCrossAxis( GraphPane pane ) { return pane.YAxis; }
/// <summary> /// Create a <see c_ref="TextObj" /> for each bar in the <see c_ref="GraphPane" />. /// </summary> /// <remarks> /// This method will go through the bars, create a label that corresponds to the bar value, /// and place it on the graph depending on user preferences. This works for horizontal or /// vertical bars in clusters or stacks, but only for <see c_ref="BarItem" /> types. This method /// does not apply to <see c_ref="ErrorBarItem" /> or <see c_ref="HiLowBarItem" /> objects. /// Call this method only after calling <see c_ref="GraphPane.AxisChange()" />. /// </remarks> /// <param name="pane">The GraphPane in which to place the text labels.</param> /// <param name="isBarCenter">true to center the labels inside the bars, false to /// place the labels just above the top of the bar.</param> /// <param name="valueFormat">The double.ToString string format to use for creating /// the labels. /// </param> public static void CreateBarLabels( GraphPane pane, bool isBarCenter, string valueFormat ) { CreateBarLabels( pane, isBarCenter, valueFormat, TextObj.Default.FontFamily, TextObj.Default.FontSize, TextObj.Default.FontColor, TextObj.Default.FontBold, TextObj.Default.FontItalic, TextObj.Default.FontUnderline ); }
/// <summary> /// Create a <see c_ref="TextObj" /> for each bar in the <see c_ref="GraphPane" />. /// </summary> /// <remarks> /// This method will go through the bars, create a label that corresponds to the bar value, /// and place it on the graph depending on user preferences. This works for horizontal or /// vertical bars in clusters or stacks, but only for <see c_ref="BarItem" /> types. This method /// does not apply to <see c_ref="ErrorBarItem" /> or <see c_ref="HiLowBarItem" /> objects. /// Call this method only after calling <see c_ref="GraphPane.AxisChange()" />. /// </remarks> /// <param name="pane">The GraphPane in which to place the text labels.</param> /// <param name="isBarCenter">true to center the labels inside the bars, false to /// place the labels just above the top of the bar.</param> /// <param name="valueFormat">The double.ToString string format to use for creating /// the labels. /// </param> /// <param name="fontColor">The color in which to draw the labels</param> /// <param name="fontFamily">The string name of the font family to use for the labels</param> /// <param name="fontSize">The floating point size of the font, in scaled points</param> /// <param name="isBold">true for a bold font type, false otherwise</param> /// <param name="isItalic">true for an italic font type, false otherwise</param> /// <param name="isUnderline">true for an underline font type, false otherwise</param> public static void CreateBarLabels( GraphPane pane, bool isBarCenter, string valueFormat, string fontFamily, float fontSize, Color fontColor, bool isBold, bool isItalic, bool isUnderline ) { bool isVertical = pane.BarSettings.Base == BarBase.X; // keep a count of the number of BarItems int curveIndex = 0; // Get a valuehandler to do some calculations for us ValueHandler valueHandler = new ValueHandler( pane, true ); // Loop through each curve in the list foreach ( CurveItem curve in pane.CurveList ) { // work with BarItems only BarItem bar = curve as BarItem; if ( bar != null ) { IPointList points = curve.Points; // ADD JKB 9/21/07 // The labelOffset should depend on whether the curve is YAxis or Y2Axis. // JHC - Generalize to any value axis // Make the gap between the bars and the labels = 1.5% of the axis range float labelOffset; Scale scale = curve.ValueAxis( pane ).Scale; labelOffset = (float)( scale._max - scale._min ) * 0.015f; // Loop through each point in the BarItem for ( int i = 0; i < points.Count; i++ ) { // Get the high, low and base values for the current bar // note that this method will automatically calculate the "effective" // values if the bar is stacked double baseVal, lowVal, hiVal; valueHandler.GetValues( curve, i, out baseVal, out lowVal, out hiVal ); // Get the value that corresponds to the center of the bar base // This method figures out how the bars are positioned within a cluster float centerVal = (float)valueHandler.BarCenterValue( bar, bar.GetBarWidth( pane ), i, baseVal, curveIndex ); // Create a text label -- note that we have to go back to the original point // data for this, since hiVal and lowVal could be "effective" values from a bar stack string barLabelText = ( isVertical ? points[i].Y : points[i].X ).ToString( valueFormat ); // Calculate the position of the label -- this is either the X or the Y coordinate // depending on whether they are horizontal or vertical bars, respectively float position; if ( isBarCenter ) position = (float)( hiVal + lowVal ) / 2.0f; else if ( hiVal >= 0 ) position = (float)hiVal + labelOffset; else position = (float)hiVal - labelOffset; // Create the new TextObj TextObj label; if ( isVertical ) label = new TextObj( barLabelText, centerVal, position ); else label = new TextObj( barLabelText, position, centerVal ); label.FontSpec.Family = fontFamily; // Configure the TextObj // CHANGE JKB 9/21/07 // CoordinateFrame should depend on whether curve is YAxis or Y2Axis. label.Location.CoordinateFrame = (isVertical && curve.IsY2Axis) ? CoordType.AxisXY2Scale : CoordType.AxisXYScale; label.FontSpec.Size = fontSize; label.FontSpec.FontColor = fontColor; label.FontSpec.IsItalic = isItalic; label.FontSpec.IsBold = isBold; label.FontSpec.IsUnderline = isUnderline; label.FontSpec.Angle = isVertical ? 90 : 0; label.Location.AlignH = isBarCenter ? AlignH.Center : ( hiVal >= 0 ? AlignH.Left : AlignH.Right ); label.Location.AlignV = AlignV.Center; label.FontSpec.Border.IsVisible = false; label.FontSpec.Fill.IsVisible = false; // Add the TextObj to the GraphPane pane.GraphObjList.Add( label ); } curveIndex++; } } }
/// <summary> /// Do all rendering associated with this <see c_ref="BarItem"/> to the specified /// <see c_ref="Graphics"/> device. This method is normally only /// called by the Draw method of the parent <see c_ref="ZedGraph.CurveList"/> /// collection 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 c_ref="ZedGraph.GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="pos">The ordinal position of the current <see c_ref="Bar"/> /// curve.</param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see c_ref="ZedGraph.GraphPane"/> object using the /// <see c_ref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> override public void Draw( Graphics g, GraphPane pane, int pos, float scaleFactor ) { // Pass the drawing onto the bar class if ( _isVisible ) _bar.DrawBars( g, pane, this, BaseAxis( pane ), ValueAxis( pane ), GetBarWidth( pane ), pos, scaleFactor ); }
/// <summary> /// Draw a legend key entry for this <see c_ref="BarItem"/> at the specified location /// </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 c_ref="ZedGraph.GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="rect">The <see c_ref="RectangleF"/> struct that specifies the /// location for the legend key</param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see c_ref="ZedGraph.GraphPane"/> object using the /// <see c_ref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> override public void DrawLegendKey( Graphics g, GraphPane pane, RectangleF rect, float scaleFactor ) { _bar.Draw( g, pane, rect, scaleFactor, true, false, null ); }
/// <summary> /// Make a value label for an <see c_ref="AxisType.Log" /> <see c_ref="Axis" />. /// </summary> /// <param name="pane"> /// A reference to the <see c_ref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="index"> /// The zero-based, ordinal index of the label to be generated. For example, a value of 2 would /// cause the third value label on the axis to be generated. /// </param> /// <param name="dVal"> /// The numeric value associated with the label. This value is ignored for log (<see c_ref="Scale.IsLog"/>) /// and text (<see c_ref="Scale.IsText"/>) type axes. /// </param> /// <returns>The resulting value label as a <see c_ref="string" /></returns> override internal string MakeLabel( GraphPane pane, int index, double dVal ) { if ( _format == null ) _format = Default.Format; if ( _isUseTenPower ) return string.Format( "{0:F0}", dVal ); return Math.Pow( 10.0, dVal ).ToString( _format ); }
/// <summary> /// Select a reasonable base 10 logarithmic axis scale given a range of data values. /// </summary> /// <remarks> /// This method only applies to <see c_ref="AxisType.Log"/> type axes, and it /// is called by the general <see c_ref="PickScale"/> method. The scale range is chosen /// based always on powers of 10 (full log cycles). This /// method honors the <see c_ref="Scale.MinAuto"/>, <see c_ref="Scale.MaxAuto"/>, /// and <see c_ref="Scale.MajorStepAuto"/> autorange settings. /// In the event that any of the autorange settings are false, the /// corresponding <see c_ref="Scale.Min"/>, <see c_ref="Scale.Max"/>, or <see c_ref="Scale.MajorStep"/> /// setting is explicitly honored, and the remaining autorange settings (if any) will /// be calculated to accomodate the non-autoranged values. For log axes, the MinorStep /// value is not used. /// <para>On Exit:</para> /// <para><see c_ref="Scale.Min"/> is set to scale minimum (if <see c_ref="Scale.MinAuto"/> = true)</para> /// <para><see c_ref="Scale.Max"/> is set to scale maximum (if <see c_ref="Scale.MaxAuto"/> = true)</para> /// <para><see c_ref="Scale.MajorStep"/> is set to scale step size (if <see c_ref="Scale.MajorStepAuto"/> = true)</para> /// <para><see c_ref="Scale.Mag"/> is set to a magnitude multiplier according to the data</para> /// <para><see c_ref="Scale.Format"/> is set to the display format for the values (this controls the /// number of decimal places, whether there are thousands separators, currency types, etc.)</para> /// </remarks> /// <param name="pane">A reference to the <see c_ref="GraphPane"/> object /// associated with this <see c_ref="Axis"/></param> /// <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="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see c_ref="GraphPane"/> object using the /// <see c_ref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <seealso c_ref="PickScale"/> /// <seealso c_ref="AxisType.Log"/> override public void PickScale( GraphPane pane, Graphics g, float scaleFactor ) { // call the base class first base.PickScale( pane, g, scaleFactor ); // Majorstep is always 1 for log scales if ( _majorStepAuto ) _majorStep = 1.0; _mag = 0; // Never use a magnitude shift for log scales //this.numDec = 0; // The number of decimal places to display is not used // Check for bad data range if ( _min <= 0.0 && _max <= 0.0 ) { _min = 1.0; _max = 10.0; } else if ( _min <= 0.0 ) { _min = _max / 10.0; } else if ( _max <= 0.0 ) { _max = _min * 10.0; } // Test for trivial condition of range = 0 and pick a suitable default if ( _max - _min < 1.0e-20 ) { if ( _maxAuto ) _max = _max * 2.0; if ( _minAuto ) _min = _min / 2.0; } // Get the nearest power of 10 (no partial log cycles allowed) if ( _minAuto ) _min = Math.Pow( 10.0, Math.Floor( Math.Log10( _min ) ) ); if ( _maxAuto ) _max = Math.Pow( 10.0, Math.Ceiling( Math.Log10( _max ) ) ); }
/// <summary> /// Setup some temporary transform values in preparation for rendering the <see c_ref="Axis"/>. /// </summary> /// <remarks> /// This method is typically called by the parent <see c_ref="GraphPane"/> /// object as part of the <see c_ref="GraphPane.Draw"/> method. It is also /// called by <see c_ref="GraphPane.GeneralTransform(double,double,CoordType)"/> and /// <see c_ref="GraphPane.ReverseTransform( PointF, out double, out double )"/> /// methods to setup for coordinate transformations. /// </remarks> /// <param name="pane"> /// A reference to the <see c_ref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="axis"> /// The parent <see c_ref="Axis" /> for this <see c_ref="Scale" /> /// </param> override public void SetupScaleData( GraphPane pane, Axis axis ) { base.SetupScaleData( pane, axis ); _minLinTemp = Linearize( _min ); _maxLinTemp = Linearize( _max ); }
/// <summary> /// Place the previously saved states of the GraphPanes on the individual GraphPane /// <see c_ref="ZedGraph.GraphPane.ZoomStack" /> collections. This provides for an /// option to undo the state change at a later time. Save a single /// (<see paramref="primaryPane" />) GraphPane if the panes are not synchronized /// (see <see c_ref="IsSynchronizeXAxes" /> and <see c_ref="IsSynchronizeYAxes" />), /// or save a list of states for all GraphPanes if the panes are synchronized. /// </summary> /// <param name="primaryPane">The primary GraphPane on which zoom/pan/scroll operations /// are taking place</param> /// <returns>The <see c_ref="ZoomState" /> that corresponds to the /// <see paramref="primaryPane" />. /// </returns> private void ZoomStatePush( GraphPane primaryPane ) { if ( _isSynchronizeXAxes || _isSynchronizeYAxes ) { for ( int i = 0; i < _masterPane._paneList.Count; i++ ) { if ( i < _zoomStateStack.Count ) _masterPane._paneList[i].ZoomStack.Add( _zoomStateStack[i] ); } } else if ( _zoomState != null ) primaryPane.ZoomStack.Add( _zoomState ); ZoomStateClear(); }
/// <summary> /// Determine the coords for the rectangle associated with a specified point for /// this <see c_ref="CurveItem" /> /// </summary> /// <param name="pane">The <see c_ref="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> override public bool GetCoords( GraphPane pane, int i, out string coords ) { coords = string.Empty; if ( i < 0 || i >= _points.Count ) return false; Axis valueAxis = ValueAxis( pane ); Axis baseAxis = BaseAxis( pane ); // 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 = 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 ( !_points[i].IsInvalid3D ) { // calculate a pixel value for the top of the bar on value axis pixLowVal = valueAxis.Scale.Transform( _isOverrideOrdinal, i, curLowVal ); pixHiVal = valueAxis.Scale.Transform( _isOverrideOrdinal, i, curHiVal ); // calculate a pixel value for the center of the bar on the base axis pixBase = baseAxis.Scale.Transform( _isOverrideOrdinal, i, curBase ); // Calculate the pixel location for the side of the bar (on the base axis) float pixSide = pixBase - clusterWidth / 2.0F + clusterGap / 2.0F + pane.CurveList.GetBarItemPos( pane, this ) * ( barWidth + barGap ); // Draw the bar if ( baseAxis is XAxis || baseAxis is X2Axis ) coords = String.Format( "{0:f0},{1:f0},{2:f0},{3:f0}", pixSide, pixLowVal, pixSide + barWidth, pixHiVal ); else coords = String.Format( "{0:f0},{1:f0},{2:f0},{3:f0}", pixLowVal, pixSide, pixHiVal, pixSide + barWidth ); return true; } return false; }
/// <summary> /// Setup the Transform Matrix to handle drawing of this <see c_ref="XAxis"/> /// </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 c_ref="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 c_ref="GraphPane"/> object using the /// <see c_ref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> override public void SetTransformMatrix( Graphics g, GraphPane pane, float scaleFactor ) { // Move the origin to the BottomLeft of the ChartRect, which is the left // side of the X axis (facing from the label side) g.TranslateTransform( pane.Chart._rect.Left, pane.Chart._rect.Bottom ); }
/// <summary> /// Gets a flag indicating if the Z data range should be included in the axis scaling calculations. /// </summary> /// <param name="pane">The parent <see c_ref="GraphPane" /> of this <see c_ref="CurveItem" />. /// </param> /// <value>true if the Z data are included, false otherwise</value> override internal bool IsZIncluded( GraphPane pane ) { return this is HiLowBarItem; }
/// <summary> /// Calculate the "shift" size, in pixels, in order to shift the axis from its default /// location to the value specified by <see c_ref="Axis.Cross"/>. /// </summary> /// <param name="pane"> /// A reference to the <see c_ref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <returns>The shift amount measured in pixels</returns> internal override float CalcCrossShift( GraphPane pane ) { double effCross = EffectiveCrossValue( pane ); if ( !_crossAuto ) return pane.YAxis.Scale.Transform( effCross ) - pane.YAxis.Scale._maxPix; return 0; }
/// <summary> /// Gets a flag indicating if the X axis is the independent axis for this <see c_ref="CurveItem" /> /// </summary> /// <param name="pane">The parent <see c_ref="GraphPane" /> of this <see c_ref="CurveItem" />. /// </param> /// <value>true if the X axis is independent, false otherwise</value> override internal bool IsXIndependent( GraphPane pane ) { return pane._barSettings.Base == BarBase.X || pane._barSettings.Base == BarBase.X2; }
/// <summary> /// Select a reasonable date-time axis scale given a range of data values. /// </summary> /// <remarks> /// This method only applies to <see c_ref="AxisType.Date"/> type axes, and it /// is called by the general <see c_ref="PickScale"/> method. The scale range is chosen /// based on increments of 1, 2, or 5 (because they are even divisors of 10). /// Note that the <see c_ref="Scale.MajorStep"/> property setting can have multiple unit /// types (<see c_ref="Scale.MajorUnit"/> and <see c_ref="Scale.MinorUnit" />), /// but the <see c_ref="Scale.Min"/> and /// <see c_ref="Scale.Max"/> units are always days (<see c_ref="XDate"/>). This /// method honors the <see c_ref="Scale.MinAuto"/>, <see c_ref="Scale.MaxAuto"/>, /// and <see c_ref="Scale.MajorStepAuto"/> autorange settings. /// In the event that any of the autorange settings are false, the /// corresponding <see c_ref="Scale.Min"/>, <see c_ref="Scale.Max"/>, or <see c_ref="Scale.MajorStep"/> /// setting is explicitly honored, and the remaining autorange settings (if any) will /// be calculated to accomodate the non-autoranged values. The basic default for /// scale selection is defined with /// <see c_ref="Scale.Default.TargetXSteps"/> and <see c_ref="Scale.Default.TargetYSteps"/> /// from the <see c_ref="Scale.Default"/> default class. /// <para>On Exit:</para> /// <para><see c_ref="Scale.Min"/> is set to scale minimum (if <see c_ref="Scale.MinAuto"/> = true)</para> /// <para><see c_ref="Scale.Max"/> is set to scale maximum (if <see c_ref="Scale.MaxAuto"/> = true)</para> /// <para><see c_ref="Scale.MajorStep"/> is set to scale step size (if <see c_ref="Scale.MajorStepAuto"/> = true)</para> /// <para><see c_ref="Scale.MinorStep"/> is set to scale minor step size (if <see c_ref="Scale.MinorStepAuto"/> = true)</para> /// <para><see c_ref="Scale.Mag"/> is set to a magnitude multiplier according to the data</para> /// <para><see c_ref="Scale.Format"/> is set to the display format for the values (this controls the /// number of decimal places, whether there are thousands separators, currency types, etc.)</para> /// </remarks> /// <param name="pane">A reference to the <see c_ref="GraphPane"/> object /// associated with this <see c_ref="Axis"/></param> /// <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="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see c_ref="GraphPane"/> object using the /// <see c_ref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <seealso c_ref="Scale.PickScale"/> /// <seealso c_ref="AxisType.Date"/> /// <seealso c_ref="Scale.MajorUnit"/> /// <seealso c_ref="Scale.MinorUnit"/> override public void PickScale( GraphPane pane, Graphics g, float scaleFactor ) { // call the base class first base.PickScale( pane, g, scaleFactor ); // Test for trivial condition of range = 0 and pick a suitable default if ( _max - _min < 1.0e-20 ) { if ( _maxAuto ) _max = _max + 0.2 * ( _max == 0 ? 1.0 : Math.Abs( _max ) ); if ( _minAuto ) _min = _min - 0.2 * ( _min == 0 ? 1.0 : Math.Abs( _min ) ); } double targetSteps = ( _ownerAxis is XAxis || _ownerAxis is X2Axis ) ? Default.TargetXSteps : Default.TargetYSteps; // Calculate the step size based on target steps double tempStep = CalcDateStepSize( _max - _min, targetSteps ); // Calculate the new step size if ( _majorStepAuto ) { _majorStep = tempStep; if ( _isPreventLabelOverlap ) { // Calculate the maximum number of labels double maxLabels = CalcMaxLabels( g, pane, scaleFactor ); if ( maxLabels < CalcNumTics() ) _majorStep = CalcDateStepSize( _max - _min, maxLabels ); } } // Calculate the scale minimum if ( _minAuto ) _min = CalcEvenStepDate( _min, -1 ); // Calculate the scale maximum if ( _maxAuto ) _max = CalcEvenStepDate( _max, 1 ); _mag = 0; // Never use a magnitude shift for date scales //this.numDec = 0; // The number of decimal places to display is not used }
/// <summary> /// Select a reasonable exponential axis scale given a range of data values. /// </summary> /// <remarks> /// This method only applies to <see c_ref="AxisType.Exponent"/> type axes, and it /// is called by the general <see c_ref="Scale.PickScale"/> method. The exponential scale /// relies on the <see c_ref="Scale.Exponent" /> property to set the scaling exponent. This /// method honors the <see c_ref="Scale.MinAuto"/>, <see c_ref="Scale.MaxAuto"/>, /// and <see c_ref="Scale.MajorStepAuto"/> autorange settings. /// In the event that any of the autorange settings are false, the /// corresponding <see c_ref="Scale.Min"/>, <see c_ref="Scale.Max"/>, or <see c_ref="Scale.MajorStep"/> /// setting is explicitly honored, and the remaining autorange settings (if any) will /// be calculated to accomodate the non-autoranged values. For log axes, the MinorStep /// value is not used. /// <para>On Exit:</para> /// <para><see c_ref="Scale.Min"/> is set to scale minimum (if <see c_ref="Scale.MinAuto"/> = true)</para> /// <para><see c_ref="Scale.Max"/> is set to scale maximum (if <see c_ref="Scale.MaxAuto"/> = true)</para> /// <para><see c_ref="Scale.MajorStep"/> is set to scale step size (if <see c_ref="Scale.MajorStepAuto"/> = true)</para> /// <para><see c_ref="Scale.Mag"/> is set to a magnitude multiplier according to the data</para> /// <para><see c_ref="Scale.Format"/> is set to the display format for the values (this controls the /// number of decimal places, whether there are thousands separators, currency types, etc.)</para> /// </remarks> /// <seealso c_ref="Scale.PickScale"/> /// <seealso c_ref="AxisType.Exponent"/> override public void PickScale( GraphPane pane, Graphics g, float scaleFactor ) { // call the base class first base.PickScale( pane, g, scaleFactor ); // Test for trivial condition of range = 0 and pick a suitable default if ( _max - _min < 1.0e-20 ) { if ( _maxAuto ) _max = _max + 0.2 * ( _max == 0 ? 1.0 : Math.Abs( _max ) ); if ( _minAuto ) _min = _min - 0.2 * ( _min == 0 ? 1.0 : Math.Abs( _min ) ); } // This is the zero-lever test. If minVal is within the zero lever fraction // of the data range, then use zero. if ( _minAuto && _min > 0 && _min / ( _max - _min ) < Default.ZeroLever ) _min = 0; // Repeat the zero-lever test for cases where the maxVal is less than zero if ( _maxAuto && _max < 0 && Math.Abs( _max / ( _max - _min ) ) < Default.ZeroLever ) _max = 0; // Calculate the new step size if ( _majorStepAuto ) { double targetSteps = ( _ownerAxis is XAxis || _ownerAxis is X2Axis ) ? Default.TargetXSteps : Default.TargetYSteps; // Calculate the step size based on target steps _majorStep = CalcStepSize( _max - _min, targetSteps ); if ( _isPreventLabelOverlap ) { // Calculate the maximum number of labels double maxLabels = CalcMaxLabels( g, pane, scaleFactor ); if ( maxLabels < ( _max - _min ) / _majorStep ) _majorStep = CalcBoundedStepSize( _max - _min, maxLabels ); } } // Calculate the new step size if ( _minorStepAuto ) _minorStep = CalcStepSize( _majorStep, ( _ownerAxis is XAxis || _ownerAxis is X2Axis ) ? Default.TargetMinorXSteps : Default.TargetMinorYSteps ); // Calculate the scale minimum if ( _minAuto ) _min = _min - MyMod( _min, _majorStep ); // Calculate the scale maximum if ( _maxAuto ) _max = MyMod( _max, _majorStep ) == 0.0 ? _max : _max + _majorStep - MyMod( _max, _majorStep ); // set the scale magnitude if required if ( _magAuto ) { // Find the optimal scale display multiple double mag = 0; double mag2 = 0; if ( Math.Abs( _min ) > 1.0e-10 ) mag = Math.Floor( Math.Log10( Math.Abs( _min ) ) ); if ( Math.Abs( _max ) > 1.0e-10 ) mag2 = Math.Floor( Math.Log10( Math.Abs( _max ) ) ); if ( Math.Abs( mag2 ) > Math.Abs( mag ) ) mag = mag2; // Do not use scale multiples for magnitudes below 4 if ( Math.Abs( mag ) <= 3 ) mag = 0; // Use a power of 10 that is a multiple of 3 (engineering scale) _mag = (int) ( Math.Floor( mag / 3.0 ) * 3.0 ); } // Calculate the appropriate number of dec places to display if required if ( _formatAuto ) { int numDec = 0 - (int) ( Math.Floor( Math.Log10( _majorStep ) ) - _mag ); if ( numDec < 0 ) numDec = 0; _format = "f" + numDec; } }
/// <summary> /// Select a reasonable ordinal axis scale given a range of data values, with the expectation that /// linear values will be displayed. /// </summary> /// <remarks> /// This method only applies to <see c_ref="AxisType.DateAsOrdinal"/> type axes, and it /// is called by the general <see c_ref="Scale.PickScale"/> method. For this type, /// the first curve is the "master", which contains the dates to be applied. /// <para>On Exit:</para> /// <para><see c_ref="Scale.Min"/> is set to scale minimum (if <see c_ref="Scale.MinAuto"/> = true)</para> /// <para><see c_ref="Scale.Max"/> is set to scale maximum (if <see c_ref="Scale.MaxAuto"/> = true)</para> /// <para><see c_ref="Scale.MajorStep"/> is set to scale step size (if <see c_ref="Scale.MajorStepAuto"/> = true)</para> /// <para><see c_ref="Scale.MinorStep"/> is set to scale minor step size (if <see c_ref="Scale.MinorStepAuto"/> = true)</para> /// <para><see c_ref="Scale.Mag"/> is set to a magnitude multiplier according to the data</para> /// <para><see c_ref="Scale.Format"/> is set to the display format for the values (this controls the /// number of decimal places, whether there are thousands separators, currency types, etc.)</para> /// </remarks> /// <param name="pane">A reference to the <see c_ref="GraphPane"/> object /// associated with this <see c_ref="Axis"/></param> /// <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="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see c_ref="GraphPane"/> object using the /// <see c_ref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <seealso c_ref="PickScale"/> /// <seealso c_ref="AxisType.Ordinal"/> override public void PickScale( GraphPane pane, Graphics g, float scaleFactor ) { // call the base class first base.PickScale( pane, g, scaleFactor ); // First, get the date ranges from the first curve in the list double xMin; // = Double.MaxValue; double xMax; // = Double.MinValue; double yMin; // = Double.MaxValue; double yMax; // = Double.MinValue; double tMin = 0; double tMax = 1; foreach ( CurveItem curve in pane.CurveList ) { if ( ( _ownerAxis is Y2Axis && curve.IsY2Axis ) || ( _ownerAxis is YAxis && !curve.IsY2Axis ) || ( _ownerAxis is X2Axis && curve.IsX2Axis ) || ( _ownerAxis is XAxis && !curve.IsX2Axis ) ) { curve.GetRange( out xMin, out xMax, out yMin, out yMax, false, false, pane ); if ( _ownerAxis is XAxis || _ownerAxis is X2Axis ) { tMin = xMin; tMax = xMax; } else { tMin = yMin; tMax = yMax; } } } double range = Math.Abs( tMax - tMin ); // Now, set the axis range based on a ordinal scale base.PickScale( pane, g, scaleFactor ); OrdinalScale.PickScale( pane, g, scaleFactor, this ); SetScaleMag( tMin, tMax, range / Default.TargetXSteps ); }
/// <summary> /// Draw the this <see c_ref="Bar"/> to the specified <see c_ref="Graphics"/> /// device as a bar at each defined point. This method /// is normally only called by the <see c_ref="BarItem.Draw"/> method of the /// <see c_ref="BarItem"/> 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 c_ref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see c_ref="CurveItem"/> object representing the /// <see c_ref="Bar"/>'s to be drawn.</param> /// <param name="baseAxis">The <see c_ref="Axis"/> class instance that defines the base (independent) /// axis for the <see c_ref="Bar"/></param> /// <param name="valueAxis">The <see c_ref="Axis"/> class instance that defines the value (dependent) /// axis for the <see c_ref="Bar"/></param> /// <param name="barWidth"> /// The width of each bar, in pixels. /// </param> /// <param name="pos"> /// The ordinal position of the this bar series (0=first bar, 1=second bar, etc.) /// in the cluster of bars. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see c_ref="GraphPane"/> object using the /// <see c_ref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void DrawBars( Graphics g, GraphPane pane, CurveItem curve, Axis baseAxis, Axis valueAxis, float barWidth, int pos, float scaleFactor ) { // For non-cluster bar types, the position is always zero since the bars are on top // of eachother BarType barType = pane._barSettings.Type; if ( barType == BarType.Overlay || barType == BarType.Stack || barType == BarType.PercentStack || barType == BarType.SortedOverlay ) pos = 0; // Loop over each defined point and draw the corresponding bar for ( int i=0; i<curve.Points.Count; i++ ) DrawSingleBar( g, pane, curve, i, pos, baseAxis, valueAxis, barWidth, scaleFactor ); }
/// <summary> /// Setup some temporary transform values in preparation for rendering the <see c_ref="Axis"/>. /// </summary> /// <remarks> /// This method is typically called by the parent <see c_ref="GraphPane"/> /// object as part of the <see c_ref="GraphPane.Draw"/> method. It is also /// called by <see c_ref="GraphPane.GeneralTransform(double,double,CoordType)"/> and /// <see c_ref="GraphPane.ReverseTransform( PointF, out double, out double )"/> /// methods to setup for coordinate transformations. /// </remarks> /// <param name="pane"> /// A reference to the <see c_ref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="axis"> /// The parent <see c_ref="Axis" /> for this <see c_ref="Scale" /> /// </param> override public void SetupScaleData( GraphPane pane, Axis axis ) { base.SetupScaleData( pane, axis ); if ( _exponent > 0 ) { _minLinTemp = Linearize( _min ); _maxLinTemp = Linearize( _max ); } else if ( _exponent < 0 ) { _minLinTemp = Linearize( _max ); _maxLinTemp = Linearize( _min ); } }
/// <summary> /// Draw the specified single bar (an individual "point") of this series to the specified /// <see c_ref="Graphics"/> device. This method is not as efficient as /// <see c_ref="DrawBars"/>, which draws the bars for all points. It is intended to be used /// only for <see c_ref="BarType.SortedOverlay"/>, which requires special handling of each bar. /// </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 c_ref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see c_ref="CurveItem"/> object representing the /// <see c_ref="Bar"/>'s to be drawn.</param> /// <param name="baseAxis">The <see c_ref="Axis"/> class instance that defines the base (independent) /// axis for the <see c_ref="Bar"/></param> /// <param name="valueAxis">The <see c_ref="Axis"/> class instance that defines the value (dependent) /// axis for the <see c_ref="Bar"/></param> /// <param name="pos"> /// The ordinal position of the this bar series (0=first bar, 1=second bar, etc.) /// in the cluster of bars. /// </param> /// <param name="index"> /// The zero-based index number for the single bar to be drawn. /// </param> /// <param name="barWidth"> /// The width of each bar, in pixels. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see c_ref="GraphPane"/> object using the /// <see c_ref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void DrawSingleBar( Graphics g, GraphPane pane, CurveItem curve, Axis baseAxis, Axis valueAxis, int pos, int index, float barWidth, float scaleFactor ) { // Make sure that a bar value exists for the current curve and current ordinal position if ( index >= curve.Points.Count ) return; // For Overlay and Stack bars, the position is always zero since the bars are on top // of eachother if ( pane._barSettings.Type == BarType.Overlay || pane._barSettings.Type == BarType.Stack || pane._barSettings.Type == BarType.PercentStack ) pos = 0; // Draw the specified bar DrawSingleBar( g, pane, curve, index, pos, baseAxis, valueAxis, barWidth, scaleFactor ); }
/// <summary> /// Make a value label for an <see c_ref="AxisType.Exponent" /> <see c_ref="Axis" />. /// </summary> /// <param name="pane"> /// A reference to the <see c_ref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="index"> /// The zero-based, ordinal index of the label to be generated. For example, a value of 2 would /// cause the third value label on the axis to be generated. /// </param> /// <param name="dVal"> /// The numeric value associated with the label. This value is ignored for log (<see c_ref="Scale.IsLog"/>) /// and text (<see c_ref="Scale.IsText"/>) type axes. /// </param> /// <returns>The resulting value label as a <see c_ref="string" /></returns> override internal string MakeLabel( GraphPane pane, int index, double dVal ) { if ( _format == null ) _format = Default.Format; double scaleMult = Math.Pow( 10.0, _mag ); double val = Math.Pow( dVal, 1 / _exponent ) / scaleMult; return val.ToString( _format ); }
/// <summary> /// Default Constructor /// </summary> public GraphControl() { InitializeComponent(); // These commands do nothing, but they get rid of the compiler warnings for // unused events bool b = MouseDown == null || MouseUp == null || MouseMove == null; // Link in these events from the base class, since we disable them from this class. base.MouseDown += ZedGraphControl_MouseDown; base.MouseUp += ZedGraphControl_MouseUp; base.MouseMove += ZedGraphControl_MouseMove; //this.MouseWheel += new System.Windows.Forms.MouseEventHandler( this.ZedGraphControl_MouseWheel ); // Use double-buffering for flicker-free updating: SetStyle( ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer | ControlStyles.ResizeRedraw, true ); //isTransparentBackground = false; //SetStyle( ControlStyles.Opaque, false ); SetStyle( ControlStyles.SupportsTransparentBackColor, true ); //this.BackColor = Color.Transparent; _resourceManager = new ResourceManager("UIGraphLib.GraphLocale", Assembly.GetExecutingAssembly() ); Rectangle rect = new Rectangle( 0, 0, Size.Width, Size.Height ); _masterPane = new MasterPane( "", rect ); _masterPane.Margin.All = 0; _masterPane.Title.IsVisible = false; string titleStr = _resourceManager.GetString( "title_def" ); string xStr = _resourceManager.GetString( "x_title_def" ); string yStr = _resourceManager.GetString( "y_title_def" ); //GraphPane graphPane = new GraphPane( rect, "Title", "X Axis", "Y Axis" ); GraphPane graphPane = new GraphPane( rect, titleStr, xStr, yStr ); using ( Graphics g = CreateGraphics() ) { graphPane.AxisChange( g ); //g.Dispose(); } _masterPane.Add( graphPane ); hScrollBar1.Minimum = 0; hScrollBar1.Maximum = 100; hScrollBar1.Value = 0; vScrollBar1.Minimum = 0; vScrollBar1.Maximum = 100; vScrollBar1.Value = 0; _xScrollRange = new ScrollRange( true ); _yScrollRangeList = new ScrollRangeList(); _y2ScrollRangeList = new ScrollRangeList(); _yScrollRangeList.Add( new ScrollRange( true ) ); _y2ScrollRangeList.Add( new ScrollRange( false ) ); _zoomState = null; _zoomStateStack = new ZoomStateStack(); }