Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

How to tell the height of a Text object?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    How to tell the height of a Text object?

    I am using Draw.Text(). It draws text into a rectangular area. I need to know how tall that area will be so that I can position it properly (Y, YPixelOffset). How do I do that?

    Prediction seems best -- can I predict the rectangle's height by knowing the font and how many lines my text will be?

    Second best would be a sequence like the following -- is this, or anything else that solves the problem, doable?
    • Inhibit refresh -- to prevent any possible flicker
    • Draw.Text()
    • Somehow force the text object object be rendered
    • Inspect the Text object for its height (object.layoutRect.Height?)
    • Position the Text object (object.Anchor.Price and object.YPixelOffset)
    • Restore refresh

    I''ve got to be overlooking some simple solution. Advice appreciated.

    Thanks
    EV
    Last edited by ETFVoyageur; 07-27-2016, 01:53 AM.

    #2
    Related question: how do I tell how many bars wide the text box is?

    BTW: I know that object.layoutRect.Height is not accessible. I have found nothing else that contains the text box's geometry. Suggestions are welcome.

    --EV
    Last edited by ETFVoyageur; 07-27-2016, 10:12 AM.

    Comment


      #3
      Hello,

      Thank you for the question.

      Because DrawingTools specifically are locked to Price and Time/BarsAgo values finding the actual bounds of the rectangle will require using logic. Because you need the bounds of the text rectangle, in essence you would need to recreate part of the Text tool in your custom logic to calculate the Size of the Text object you create.

      If you review the @Text.cs drawing tool file, you can see the exact logic being used currently to measure the string and set the text size etc.

      I created a small sample to show how to get the 4 corners of a text object in the same way the @Text tool measures.

      Please note this does not account for the border of the object and is only based off of the texts Anchor point. Additionally this specifically references Panel 0 of the chart, to test this would need to be overlaid on the primary panel. Finally this does require chartScale because you are dealing with Heights, the Scale is important in order to find the Correct Y values depending on the current scale.

      As far as getting a number of bars the text tool spans, you could look into using the X values you get for the Left and the Right to get SlotIndexes. With these Indexes, you could use math to get the total number between the two returned values.

      Code:
      private Text myText;
      private string myTextContent = "Testing";
      
      protected override void OnBarUpdate()
      {
      
      	if (State == State.Historical) return;
      	myText = Draw.Text(this, "test", true, myTextContent, 0, Close[0], 0, Brushes.Red, new SimpleFont("Arial", 12), TextAlignment.Center, Brushes.Transparent, Brushes.Black, 45);
      }
      
      protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
      {
      	if (myText != null)
      	{
      		SharpDX.DirectWrite.TextFormat textFormat = myText.Font.ToDirectWriteTextFormat();
      		SharpDX.DirectWrite.TextLayout layout = new SharpDX.DirectWrite.TextLayout(Core.Globals.DirectWriteFactory, myTextContent, textFormat, chartControl.ChartPanels[0].W, textFormat.FontSize);
      		float startX = chartControl.GetXByTime(myText.Anchor.Time);
      		float startY = chartScale.GetYByValue(myText.Anchor.Price);
      		Print(startX + " " + startY);
      
      		float yTop = startY - layout.Metrics.Height / 2;
      		float yBottom = startY + layout.Metrics.Height / 2;
      		float xLeft = startX - layout.Metrics.Width / 2;
      		float xRight = startX + layout.Metrics.Width / 2;
      
      		RenderTarget.FillEllipse(new SharpDX.Direct2D1.Ellipse(new SharpDX.Vector2(xLeft, yTop), 8, 8), Brushes.Blue.ToDxBrush(RenderTarget));
      		RenderTarget.FillEllipse(new SharpDX.Direct2D1.Ellipse(new SharpDX.Vector2(xLeft, yBottom), 8, 8), Brushes.Blue.ToDxBrush(RenderTarget));
      		RenderTarget.FillEllipse(new SharpDX.Direct2D1.Ellipse(new SharpDX.Vector2(xRight, yTop), 8, 8), Brushes.Blue.ToDxBrush(RenderTarget));
      		RenderTarget.FillEllipse(new SharpDX.Direct2D1.Ellipse(new SharpDX.Vector2(xRight, yBottom), 8, 8), Brushes.Blue.ToDxBrush(RenderTarget));
      	}
      
      	base.OnRender(chartControl, chartScale);
      }
      I look forward to being of further assistance.
      JesseNinjaTrader Customer Service

      Comment


        #4
        Originally posted by ETFVoyageur View Post
        I am using Draw.Text(). It draws text into a rectangular area. I need to know how tall that area will be so that I can position it properly (Y, YPixelOffset). How do I do that?

        Prediction seems best -- can I predict the rectangle's height by knowing the font and how many lines my text will be?

        Second best would be a sequence like the following -- is this, or anything else that solves the problem, doable?
        • Inhibit refresh -- to prevent any possible flicker
        • Draw.Text()
        • Somehow force the text object object be rendered
        • Inspect the Text object for its height (object.layoutRect.Height?)
        • Position the Text object (object.Anchor.Price and object.YPixelOffset)
        • Restore refresh

        I''ve got to be overlooking some simple solution. Advice appreciated.

        Thanks
        EV
        From some old threads of which you were a part:

        ref: http://ninjatrader.com/support/forum...ad.php?t=77478

        Comment


          #5
          Jesse,

          Thanks for your help. The two lines that create the textFormat and layout objects are just what I need. Together with the magic padding constant (10.5) from Text.cs it works fine.

          That said, I am not happy to have to hard-code an internal magic constant -- that makes for fragile code, because that constant could easily change in a future release. There really needs to be a fully-supported way to get the geometry of the area that will be used by a call to Draw.Text()

          Anyway, thanks again. My code, fragile or not, is working fine now. The text is getting positioned exactly where I want it.

          --EV

          Note: for anyone who is not sure what the problem is: the basic calls will position the center of the text area just fine. You an set the Y value and a pixel offset to do what you need to do. What you cannot do without the information this thread provides is to position the top or bottom of the text area accurately, because without knowing the area's height you do not know what pixel offset to specify.
          Last edited by ETFVoyageur; 07-27-2016, 08:02 PM.

          Comment

          Latest Posts

          Collapse

          Topics Statistics Last Post
          Started by Mikey_, 03-23-2024, 05:59 PM
          3 responses
          49 views
          0 likes
          Last Post Sam2515
          by Sam2515
           
          Started by f.saeidi, Today, 12:14 PM
          7 responses
          17 views
          0 likes
          Last Post f.saeidi  
          Started by Russ Moreland, Today, 12:54 PM
          1 response
          6 views
          0 likes
          Last Post NinjaTrader_Erick  
          Started by philmg, Today, 12:55 PM
          1 response
          7 views
          0 likes
          Last Post NinjaTrader_ChristopherJ  
          Started by TradeForge, 04-19-2024, 02:09 AM
          2 responses
          32 views
          0 likes
          Last Post TradeForge  
          Working...
          X