/// <summary> /// /// </summary> /// <param name="OutputStream"></param> /// <param name="Format"></param> /// <param name="bShowTransparency">if true, draw squares instead of leaving the /// background transparent</param> /// <remarks> /// bShowTransparency is set to true in design mode, to false otherwise. /// </remarks> protected MasterPane CreateGraph( System.IO.Stream OutputStream, ImageFormat Format, bool bShowTransparency ) { RectangleF rect = new RectangleF( 0, 0, this.Width, this.Height ); MasterPane mp = new MasterPane( string.Empty, rect ); mp.Margin.All = 0; mp.Fill.IsVisible = false; mp.Border.IsVisible = false; // create all required panes //for ( int i = 0; i < this.PaneCount; i++ ) //{ mp.Add( new GraphPane( rect, Title, string.Empty, string.Empty ) ); //} // create output bitmap container Bitmap image = new Bitmap( this.Width, this.Height ); using ( Graphics g = Graphics.FromImage( image ) ) { // Apply layout plan //mp.SetLayout( this.PaneLayout ); mp.ReSize( g, rect ); // Use callback to gather more settings and data values OnDrawPane( g, mp ); // Allow designer control of axischange if ( this.AxisChanged ) mp.AxisChange( g ); // Render the graph to a bitmap if ( bShowTransparency && mp.Fill.Color.A != 255 ) { //Show the transparency as white/gray filled squares // We need to add the resource namespace to its name //string resourceName = string.Format( "{0}.transparency.png", GetType().Namespace ); string resourceName = "ZedGraph.ZedGraph.transparency.png"; Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream( resourceName ); if ( stream == null ) throw new Exception( "Does the Build Action of the resource " + resourceName + " is set to Embedded Resource ?" ); using ( System.Drawing.Image brushImage = new Bitmap( stream ) ) using ( TextureBrush brush = new TextureBrush( brushImage, WrapMode.Tile ) ) { g.FillRectangle( brush, 0, 0, this.Width, this.Height ); } stream.Close(); } mp.Draw( g ); } // Stream the graph out MemoryStream ms = new MemoryStream(); image.Save( ms, Format ); //TODO: provide caching options ms.WriteTo( OutputStream ); return mp; }
/// <summary> /// stub method that passes control for the render event to the the registered /// event handler. /// </summary> protected virtual void OnDrawPane( Graphics g, MasterPane mp ) { ZeeGraphWebControlEventHandler handler; handler = (ZeeGraphWebControlEventHandler)Events[_eventRender]; MasterPaneFill.CopyTo( mp.Fill ); MasterPaneBorder.CopyTo( mp.Border ); if ( ( handler == null ) && ( CurveList.Count == 0 ) && ( GraphObjList.Count == 0 ) ) { // default with the sample graph if no callback provided foreach ( GraphPane p in mp.PaneList ) { ZeeGraphWeb.RenderDemo( g, p ); } } else { foreach ( GraphPane p in mp.PaneList ) { // Add visual designer influences here - first!! SetWebProperties( g, p ); // Add DataSource values if available before the callback PopulateByDataSource( g, p ); //Add Graph Items AddWebGraphItems( g, p ); } //TODO: verify callback regression test // Add custom callback tweeking next if ( handler != null ) handler( this, g, mp ); // Set the layout according to user preferences mp.ReSize( g ); } }
/// <summary> /// The Copy Constructor - Make a deep-copy clone of this class instance. /// </summary> /// <param name="rhs">The <see cref="MasterPane"/> object from which to copy</param> public MasterPane( MasterPane rhs ) : base(rhs) { // copy all the value types //_paneLayoutMgr = rhs._paneLayoutMgr.Clone(); _innerPaneGap = rhs._innerPaneGap; _isUniformLegendEntries = rhs._isUniformLegendEntries; _isCommonScaleFactor = rhs._isCommonScaleFactor; // Then, fill in all the reference types with deep copies _paneList = rhs._paneList.Clone(); _paneLayout = rhs._paneLayout; _countList = rhs._countList; _isColumnSpecified = rhs._isColumnSpecified; _prop = rhs._prop; _isAntiAlias = rhs._isAntiAlias; }
/// <summary> /// Generate an ImageMap as Html tags /// </summary> /// <param name="masterPane">The source <see cref="MasterPane" /> to be /// image mapped.</param> /// <param name="output">An <see cref="HtmlTextWriter" /> instance in which /// the html tags will be written for the image map.</param> public void MakeImageMap( MasterPane masterPane, HtmlTextWriter output ) { string shape; string coords; Bitmap image = new Bitmap( 1, 1 ); using ( Graphics g = Graphics.FromImage( image ) ) { float masterScale = masterPane.CalcScaleFactor(); // Frontmost objects are MasterPane objects with A_InFront foreach ( GraphObj obj in masterPane.GraphObjList ) { if ( obj.Link.IsActive && obj.ZOrder == ZOrder.A_InFront ) { obj.GetCoords( masterPane, g, masterScale, out shape, out coords ); MakeAreaTag( shape, coords, obj.Link.Url, obj.Link.Target, obj.Link.Title, obj.Link.Tag, output ); } } // Now loop over each GraphPane foreach ( GraphPane pane in masterPane.PaneList ) { float scaleFactor = pane.CalcScaleFactor(); // Next comes GraphPane GraphObjs in front of data points foreach ( GraphObj obj in pane.GraphObjList ) { if ( obj.Link.IsActive && obj.IsInFrontOfData ) { obj.GetCoords( pane, g, scaleFactor, out shape, out coords ); MakeAreaTag( shape, coords, obj.Link.Url, obj.Link.Target, obj.Link.Title, obj.Link.Tag, output ); } } // Then come the data points (CurveItems) foreach ( CurveItem curve in pane.CurveList ) { if ( curve.Link.IsActive && curve.IsVisible ) { for ( int i=0; i < (curve is PieItem ? 1 : curve.Points.Count); i++ ) { //if ( curve.GetCoords( pane, i, pane.Rect.Left, pane.Rect.Top, out coords ) ) if ( curve.GetCoords( pane, i, out coords ) ) { if ( curve is PieItem ) { MakeAreaTag( "poly", coords, curve.Link.Url, curve.Link.Target, curve.Link.Title, curve.Link.Tag, output ); // only one point for PieItems break; } else { // Add an "?index=4" type tag to the url to indicate which // point was selected string url; if ( curve.Link.Url != string.Empty ) url = curve.Link.MakeCurveItemUrl( pane, curve, i ); else url = ""; string title = curve.Link.Title; if ( curve.Points[i].Tag is string ) title = curve.Points[i].Tag as string; MakeAreaTag( "rect", coords, url, curve.Link.Target, title, curve.Points[i].Tag, output ); } } } } } // Then comes the GraphObjs behind the data points foreach ( GraphObj obj in pane.GraphObjList ) { if ( obj.Link.IsActive && !obj.IsInFrontOfData ) { obj.GetCoords( pane, g, scaleFactor, out shape, out coords ); MakeAreaTag( shape, coords, obj.Link.Url, obj.Link.Target, obj.Link.Title, obj.Link.Tag, output ); } } } // Hindmost objects are MasterPane objects with !A_InFront foreach ( GraphObj obj in masterPane.GraphObjList ) { if ( obj.Link.IsActive && obj.ZOrder != ZOrder.A_InFront ) { obj.GetCoords( masterPane, g, masterScale, out shape, out coords ); MakeAreaTag( shape, coords, obj.Link.Url, obj.Link.Target, obj.Link.Title, obj.Link.Tag, output ); } } } }
/// <summary> /// Mark the <see cref="CurveItem" />'s that are included in the selection list /// by setting the <see cref="CurveItem.IsSelected" /> property to true. /// </summary> /// <param name="master">The <see cref="MasterPane" /> that "owns" the selection list.</param> public void UpdateSelection( MasterPane master ) { if ( Count <= 0 ) { ClearSelection( master ); return; } foreach ( GraphPane pane in master.PaneList ) { foreach ( CurveItem ci in pane.CurveList ) { //Make it Inactive ci.IsSelected = false; } } foreach ( CurveItem ci in this ) { //Make Active ci.IsSelected = true; //If it is a line / scatterplot, the selected Curve may be occluded by an unselected Curve //So, move it to the top of the ZOrder by removing it, and re-adding it. //Why only do this for Lines? ...Bar and Pie Curves are less likely to overlap, //and adding and removing Pie elements changes thier display order if ( ci.IsLine ) { //I don't know how to get a Pane, from a CurveItem, so I can only do it //if there is one and only one Pane, based on the assumption that the //Curve's Pane is MasterPane[0] //If there is only one Pane if ( master.PaneList.Count == 1 ) { GraphPane pane = master.PaneList[0]; pane.CurveList.Remove( ci ); pane.CurveList.Insert( 0, ci ); } } } //Send Selection Changed Event if ( SelectionChangedEvent != null ) SelectionChangedEvent( this, new EventArgs() ); }
/// <summary> /// Add a <see cref="CurveItem" /> to the selection list. /// </summary> /// <param name="master">The <see cref="MasterPane" /> that is the "owner" /// of the <see cref="CurveItem" />'s.</param> /// <param name="ci">The <see cref="CurveItem" /> to be added to the list.</param> public void AddToSelection( MasterPane master, CurveItem ci ) { if ( this.Contains( ci ) == false ) Add( ci ); UpdateSelection( master ); }
/// <summary> /// Place a list of <see cref="CurveItem" />'s in the selection list, removing all other /// items. /// </summary> /// <param name="master">The <see cref="MasterPane" /> that is the "owner" /// of the <see cref="CurveItem" />'s.</param> /// <param name="ciList">The list of <see cref="CurveItem" /> to be added to the list.</param> public void Select( MasterPane master, CurveList ciList ) { //Clear the selection, but don't send the event, //the event will be sent in "AddToSelection" by calling "UpdateSelection" ClearSelection( master, false ); AddToSelection( master, ciList ); }
/// <summary> /// Remove the specified <see cref="CurveItem" /> from the selection list. /// </summary> /// <param name="master">The <see cref="MasterPane" /> that is the "owner" /// of the <see cref="CurveItem" />'s.</param> /// <param name="ci">The <see cref="CurveItem" /> to be removed from the list.</param> public void RemoveFromSelection( MasterPane master, CurveItem ci ) { if ( this.Contains( ci ) ) this.Remove( ci ); UpdateSelection( master ); }
/// <summary> /// Clear the selection list and optionally trigger a <see cref="SelectionChangedEvent" />. /// </summary> /// <param name="master">The <see cref="MasterPane" /> that "owns" the selection list.</param> /// <param name="sendEvent">true to trigger a <see cref="SelectionChangedEvent" />, /// false otherwise.</param> public void ClearSelection( MasterPane master, bool sendEvent ) { this.Clear(); foreach ( GraphPane pane in master.PaneList ) { foreach ( CurveItem ci in pane.CurveList ) { ci.IsSelected = false; } } if ( sendEvent ) { if ( SelectionChangedEvent != null ) SelectionChangedEvent( this, new EventArgs() ); } }
/// <summary> /// Clear the selection list and trigger a <see cref="SelectionChangedEvent" />. /// </summary> /// <param name="master">The <see cref="MasterPane" /> that "owns" the selection list.</param> public void ClearSelection( MasterPane master ) { ClearSelection( master, true ); }
/// <summary> /// Add a list of <see cref="CurveItem" />'s to the selection list. /// </summary> /// <param name="master">The <see cref="MasterPane" /> that is the "owner" /// of the <see cref="CurveItem" />'s.</param> /// <param name="ciList">The list of <see cref="CurveItem" />'s to be added to the list.</param> public void AddToSelection( MasterPane master, CurveList ciList ) { foreach ( CurveItem ci in ciList ) { if ( this.Contains( ci ) == false ) this.Add( ci ); } UpdateSelection( master ); }