public void Render( IGraphCanvas graphics, GraphTransform transform, IGraph2dSource data, PointF cursorDataPt, bool enabled ) { foreach ( IGraph2dRenderer renderer in m_Renderers ) { renderer.Render( graphics, transform, data, cursorDataPt, enabled ); } }
/// <summary> /// Renders graph data /// </summary> /// <param name="graphics">Graphics object to render into</param> /// <param name="transform">Graph transform</param> /// <param name="data">Data to render</param> /// <param name="cursorDataPt">Position of the mouse cursor in data space</param> /// <param name="enabled">The enabled state of the graph control</param> public void Render( IGraphCanvas graphics, GraphTransform transform, IGraph2dSource data, PointF cursorDataPt, bool enabled ) { IGraphX2dSampleSource sampleSource = ( IGraphX2dSampleSource )data; int sample = ( int )( transform.DataBounds.Left / sampleSource.XStepPerSample ); Color darkColour = GraphUtils.ScaleColour( m_Colour, 0.2f ); float hStep = sampleSource.XStepPerSample / 2; float dataX = ( sample * sampleSource.XStepPerSample ) + hStep; while ( dataX < transform.DataBounds.Right ) { float value = sampleSource.Evaluate( dataX ); dataX += sampleSource.XStepPerSample; Point tl = transform.DataToScreen( new PointF( dataX - hStep, value ) ); Point br = transform.DataToScreen( new PointF( dataX + hStep, 0 ) ); if ( ( br.Y - tl.Y ) == 0 ) { continue; } Rectangle barArea = new Rectangle( tl.X - 1, tl.Y, ( br.X - tl.X ) + 1, br.Y - tl.Y ); using ( LinearGradientBrush brush = new LinearGradientBrush( barArea, m_Colour, darkColour, 90.0f ) ) { brush.InterpolationColors = m_Blends; graphics.FillRectangle( brush, barArea ); } } }
/// <summary> /// Renders a graph using this renderer /// </summary> public void Render( IGraphCanvas graphics, GraphTransform transform, IGraph2dSource data, PointF cursorDataPt, bool enabled ) { Graph2dSourceUniformValue uniformData = ( Graph2dSourceUniformValue )data; if ( uniformData.FixedAxis == Graph2dSourceUniformValue.Axis.X ) { float dataX = transform.DataToScreen( new PointF( uniformData.Value, 0 ) ).X; // TODO: Need to if ( Math.Abs( cursorDataPt.X - uniformData.Value ) < transform.ScreenToDataXScale * Graph2dUniformValueController.ScreenSelectionTolerance ) { graphics.DrawLine( s_HighlightPen, dataX, transform.DrawBounds.Top, dataX, transform.DrawBounds.Bottom ); } graphics.DrawLine( m_Pen, dataX, transform.DrawBounds.Top, dataX, transform.DrawBounds.Bottom ); } else { float dataY = transform.DataToScreen( new PointF( 0, uniformData.Value ) ).Y; if ( Math.Abs( cursorDataPt.Y - uniformData.Value ) < transform.ScreenToDataYScale * Graph2dUniformValueController.ScreenSelectionTolerance ) { graphics.DrawLine( s_HighlightPen, transform.DrawBounds.Left, dataY, transform.DrawBounds.Right, dataY ); } graphics.DrawLine( m_Pen, transform.DrawBounds.Left, dataY, transform.DrawBounds.Right, dataY ); } }
/// <summary> /// Called by the control owner when the left mouse button is pressed /// </summary> /// <param name="data">Graph data</param> /// <param name="transform">Graph view transform</param> /// <param name="dataX">Mouse X position in data space</param> /// <param name="dataY">Mouse Y position in data space</param> /// <param name="down">True if the button was pressed, false if the button was released</param> /// <returns>Returns true if the event was handled, and the control owner should perform no further processing</returns> public override bool OnMouseLeftButton( IGraph2dSource data, GraphTransform transform, float dataX, float dataY, bool down ) { if ( !down || data.Disabled ) { m_MovingIndices = null; return false; } GraphX2dSourceFunction1dAdapter pwlData = ( GraphX2dSourceFunction1dAdapter )data; PiecewiseLinearFunction1d pwlFunc = ( PiecewiseLinearFunction1d )pwlData.Function; float selectionDistance = transform.ScreenToDataYScale * ScreenSelectionTolerance; int closestCpIndex = pwlFunc.FindControlPoint( new Point2( dataX, dataY ), selectionDistance ); if ( closestCpIndex != -1 ) { m_MovingIndices = new int[] { closestCpIndex }; return true; } int closestCp0; int closestCp1; if ( GetLineNear( pwlFunc, new Point2( dataX, dataY ), out closestCp0, out closestCp1, selectionDistance ) ) { m_MovingIndices = new int[] { closestCp0, closestCp1 }; return true; } return false; }
/// <summary> /// Called by the control owner when the left mouse button is pressed /// </summary> /// <param name="data">Graph data</param> /// <param name="transform">Graph view transform</param> /// <param name="dataX">Mouse X position in data space</param> /// <param name="dataY">Mouse Y position in data space</param> /// <param name="down">True if the button was pressed, false if the button was released</param> /// <returns>Returns true if the event was handled, and the control owner should perform no further processing</returns> public override bool OnMouseLeftButton( IGraph2dSource data, GraphTransform transform, float dataX, float dataY, bool down ) { if ( !down || data.Disabled ) { m_Moving = false; return false; } float selectionDistance = transform.ScreenToDataYScale * ScreenSelectionTolerance; Graph2dSourceUniformValue uniformData = (Graph2dSourceUniformValue)data; float value = uniformData.FixedAxis == Graph2dSourceUniformValue.Axis.X ? dataX : dataY; m_Moving = Math.Abs( value - uniformData.Value ) < selectionDistance; return false; }
/// <summary> /// Called by the control owner when the mouse is moved /// </summary> /// <param name="data">Graph data</param> /// <param name="transform">Graph view transform</param> /// <param name="lastDataX">Previous mouse X position in data space</param> /// <param name="lastDataY">Previous mouse Y position in data space</param> /// <param name="dataX">Mouse X position in data space</param> /// <param name="dataY">Mouse Y position in data space</param> /// <returns>Returns true if the event was handled, and the control owner should perform no further processing</returns> public override bool OnMouseMove( IGraph2dSource data, GraphTransform transform, float lastDataX, float lastDataY, float dataX, float dataY ) { if ( data.Disabled || !m_Moving ) { return false; } Graph2dSourceUniformValue uniformData = ( Graph2dSourceUniformValue )data; if ( uniformData.FixedAxis == Graph2dSourceUniformValue.Axis.X ) { uniformData.Value += dataX - lastDataX; } else { uniformData.Value += dataY - lastDataY; } return false; }
/// <summary> /// Renders the graph /// </summary> public void Render( IGraphCanvas graphics, GraphTransform transform, IGraph2dSource data, PointF cursorDataPt, bool enabled ) { Pen pen = ( enabled && !data.Disabled ) ? m_Pen : s_DisabledPen; Pen shadowPen = GetShadowPen( data ); GraphX2dSourceFunction1dAdapter cpData = ( GraphX2dSourceFunction1dAdapter )data; PiecewiseLinearFunction1d pwl = ( PiecewiseLinearFunction1d )cpData.Function; float tolerance = transform.ScreenToDataYScale * GraphX2dControlPointController.ScreenSelectionTolerance; int highlightCpIndex = IndexOfControlPointNearPoint( pwl.ControlPoints, new Point2( cursorDataPt.X, cursorDataPt.Y ), tolerance ); Point2 cp = pwl[ 0 ]; Point lastPt = transform.DataToScreen( new PointF( cp.X, cp.Y ) ); if ( NoEndPoints ) { Point edgePt = transform.DataToScreen( new PointF( transform.DataBounds.Left, cp.Y ) ); DrawGraphLine( graphics, pen, shadowPen, enabled, lastPt, edgePt ); } for ( int cpIndex = 1; cpIndex < pwl.NumControlPoints; ++cpIndex ) { cp = pwl[ cpIndex ]; Point pt = transform.DataToScreen( new PointF( cp.X, cp.Y ) ); DrawGraphLine( graphics, pen, shadowPen, enabled, lastPt, pt ); DrawControlPoint( graphics, lastPt, enabled ? m_Brush : s_DisabledBrush, highlightCpIndex == ( cpIndex - 1 ) ); lastPt = pt; } if ( NoEndPoints ) { Point edgePt = transform.DataToScreen( new PointF( transform.DataBounds.Right, cp.Y ) ); DrawGraphLine( graphics, pen, shadowPen, enabled, lastPt, edgePt ); } DrawControlPoint( graphics, lastPt, Brushes.Blue, highlightCpIndex == ( pwl.NumControlPoints - 1 ) ); }
/// <summary> /// Renders control points in a graph that derives from Graph2dPiecewiseLinear /// </summary> public void Render( IGraphCanvas graphics, GraphTransform transform, IGraph2dSource data, PointF cursorDataPt, bool enabled ) { if ( data.Disabled ) { return; } GraphX2dSourceFunction1dAdapter pwlGraph = ( GraphX2dSourceFunction1dAdapter )data; PiecewiseLinearFunction1d pwlFunc = ( PiecewiseLinearFunction1d )pwlGraph.Function; float tolerance = transform.ScreenToDataYScale * GraphX2dControlPointController.ScreenSelectionTolerance; int highlightCpIndex = pwlFunc.FindControlPoint( new Point2( cursorDataPt.X, cursorDataPt.Y ), tolerance ); for ( int cpIndex = 0; cpIndex < pwlFunc.NumControlPoints; ++cpIndex ) { Point2 cp = pwlFunc[ cpIndex ]; PointF screenPt = transform.DataToScreen( new PointF( cp.X, cp.Y ) ); graphics.FillCircle( m_CpBrush, screenPt.X, screenPt.Y, 2 ); if ( cpIndex == highlightCpIndex ) { graphics.DrawCircle( s_HighlightPen, screenPt.X, screenPt.Y, 4 ); } } }
/// <summary> /// Called by the control owner when the right mouse button is pressed /// </summary> /// <param name="data">Graph data</param> /// <param name="transform">Graph view transform</param> /// <param name="dataX">Mouse X position in data space</param> /// <param name="dataY">Mouse Y position in data space</param> /// <param name="down">True if the button was pressed, false if the button was released</param> /// <returns>Returns true if the event was handled, and the control owner should perform no further processing</returns> public virtual bool OnMouseRightButton( IGraph2dSource data, GraphTransform transform, float dataX, float dataY, bool down ) { return false; }
/// <summary> /// Called by the control owner when the mouse is moved /// </summary> /// <param name="data">Graph data</param> /// <param name="transform">Graph view transform</param> /// <param name="lastDataX">Previous mouse X position in data space</param> /// <param name="lastDataY">Previous mouse Y position in data space</param> /// <param name="dataX">Mouse X position in data space</param> /// <param name="dataY">Mouse Y position in data space</param> /// <returns>Returns true if the event was handled, and the control owner should perform no further processing</returns> public virtual bool OnMouseMove( IGraph2dSource data, GraphTransform transform, float lastDataX, float lastDataY, float dataX, float dataY ) { return false; }
/// <summary> /// Called by the control owner when the mouse is moved /// </summary> /// <param name="data">Graph data</param> /// <param name="transform">Graph view transform</param> /// <param name="lastDataX">Previous mouse X position in data space</param> /// <param name="lastDataY">Previous mouse Y position in data space</param> /// <param name="dataX">Mouse X position in data space</param> /// <param name="dataY">Mouse Y position in data space</param> /// <returns>Returns true if the event was handled, and the control owner should perform no further processing</returns> public override bool OnMouseMove( IGraph2dSource data, GraphTransform transform, float lastDataX, float lastDataY, float dataX, float dataY ) { if ( data.Disabled || m_MovingIndices == null ) { return false; } GraphX2dSourceFunction1dAdapter pwlData = ( GraphX2dSourceFunction1dAdapter )data; PiecewiseLinearFunction1d pwlFunc = ( PiecewiseLinearFunction1d )pwlData.Function; int lastCpIndex = pwlFunc.NumControlPoints - 1; foreach ( int cpIndex in m_MovingIndices ) { if ( cpIndex == -1 ) { continue; } Point2 cp = pwlFunc[ cpIndex ]; float deltaX = dataX - lastDataX; float deltaY = dataY - lastDataY; // Clamp new control point (x,y) to the bounds of the data source float x = Rb.Core.Maths.Utils.Clamp( cp.X + deltaX, data.MinimumX, data.MaximumX ); float y = Rb.Core.Maths.Utils.Clamp( cp.Y + deltaY, data.MinimumY, data.MaximumY ); // Clamp new control point x to the two neighbouring control points if ( ( cpIndex > 0 ) && ( x < pwlFunc[ cpIndex - 1 ].X ) ) { x = pwlFunc[ cpIndex - 1 ].X; } else if ( ( cpIndex < lastCpIndex ) && ( x > pwlFunc[ cpIndex + 1 ].X ) ) { x = pwlFunc[ cpIndex + 1 ].X; } pwlFunc[ cpIndex ] = new Point2( x, y ); } return true; }
/// <summary> /// Called by the control owner when the right mouse button is pressed /// </summary> /// <param name="data">Graph data</param> /// <param name="transform">Graph view transform</param> /// <param name="dataX">Mouse X position in data space</param> /// <param name="dataY">Mouse Y position in data space</param> /// <param name="down">True if the button was pressed, false if the button was released</param> /// <returns>Returns true if the event was handled, and the control owner should perform no further processing</returns> public override bool OnMouseRightButton( IGraph2dSource data, GraphTransform transform, float dataX, float dataY, bool down ) { if ( !data.Selected || data.Disabled || !down ) { return false; } GraphX2dSourceFunction1dAdapter pwlData = ( GraphX2dSourceFunction1dAdapter )data; PiecewiseLinearFunction1d pwlFunc = ( PiecewiseLinearFunction1d )pwlData.Function; int deleteIndex = pwlFunc.FindControlPoint( new Point2( dataX, dataY ), transform.ScreenToDataYScale * ScreenSelectionTolerance ); if ( deleteIndex != -1 ) { pwlFunc.RemoveControlPoint( deleteIndex ); return false; } int insertAfterIndex = 0; for (; insertAfterIndex < pwlFunc.NumControlPoints; ++insertAfterIndex ) { if ( dataX < pwlFunc[ insertAfterIndex ].X ) { break; } } pwlFunc.InsertControlPoint( insertAfterIndex, new Point2( dataX, dataY ) ); return true; }
/// <summary> /// Renders graph data /// </summary> /// <param name="graphics">Graphics object to render into</param> /// <param name="transform">Graph view transform</param> /// <param name="data">Data to render</param> /// <param name="cursorDataPt">Position of the mouse cursor in data space</param> /// <param name="enabled">The enabled state of the graph control</param> public virtual void Render( IGraphCanvas graphics, GraphTransform transform, IGraph2dSource data, PointF cursorDataPt, bool enabled ) { IGraphX2dSource eval = ( IGraphX2dSource )data; Pen pen = ( enabled && !data.Disabled ) ? m_Pen : s_DisabledPen; Pen shadowPen = null; if ( !data.Disabled ) { if ( data.Selected ) { shadowPen = s_SelectedPen; } else if ( data.Highlighted ) { shadowPen = s_HighlightedPen; } } float dataX = transform.DataBounds.Left; float dataXInc = transform.DataBounds.Width / transform.DrawBounds.Width; Point lastPt = transform.DataToScreen( new PointF( dataX, eval.Evaluate( dataX ) ) ) ; dataX += dataXInc; for ( int drawX = 1; drawX < transform.DrawBounds.Width; ++drawX, dataX += dataXInc ) { Point pt = transform.DataToScreen( new PointF( dataX, eval.Evaluate( dataX ) ) ); graphics.DrawLine( pen, lastPt.X, lastPt.Y, pt.X, pt.Y ); if ( enabled && shadowPen != null ) { graphics.DrawLine( shadowPen, lastPt.X, lastPt.Y + 1, pt.X, pt.Y + 1 ); graphics.DrawLine( shadowPen, lastPt.X, lastPt.Y - 1, pt.X, pt.Y - 1 ); } lastPt = pt; } }