DLine Axis Assignment Reference issue

TeeChart for ActiveX, COM and ASP
Post Reply
tirby
Newbie
Newbie
Posts: 84
Joined: Mon Mar 16, 2009 12:00 am

DLine Axis Assignment Reference issue

Post by tirby » Sun Jun 09, 2013 5:12 pm

Hi,

This is difficult to put into words, so I've included a project to demonstrate the issue.

The Left Axis is set to 50.
The Right Axis is set to 20,000.
When a DLine is created, it appears to automatically set it’s Axis reference (for use in calculating it’s position) to the Left Axis – if it’s active. If not, then it defaults to the Right Axis.

So, drawing a DLine that needs to be associated with the Left Axis is visible when the Left Axis is active. Likewise, if the Left Axis is not active but the Right Axis is, then the DLine is referenced to the Right Axis. If both DLines are required to be visible, and both Axis’s are required to be visible, then the DLine’s position that is referenced to the Right Axis is calculated based on the Left Axis, and consequently ends up off scale at the top, or lined up on top of each other at zero Y value.

Using the CalcPosValue and CalcPosPoint, the correct position can be determined based on whichever Axis (scales) one selects, however, when displaying the DLines, these functions return values that are not within the correct axis domain.

At present, I’m only using the standard Left & Right Axis's, but in the near future, I will be modifying to include multiple Left and Right Custom Axis’s, and I fear this issue may be a problem there also.

Can you assist?

Thanks!
Attachments
DLineTest.Zip
(3.6 KiB) Downloaded 1127 times

Yeray
Site Admin
Site Admin
Posts: 9587
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: DLine Axis Assignment Reference issue

Post by Yeray » Mon Jun 10, 2013 8:17 am

Hello tirby,
tirby wrote:Using the CalcPosValue and CalcPosPoint, the correct position can be determined based on whichever Axis (scales) one selects, however, when displaying the DLines, these functions return values that are not within the correct axis domain.
I think you only missed to force a chart redraw before using these functions.
I've changed your code for this and it seems to work fine for me here. I only take the the values in the line relative to the right axis scale, calculated the pixels they correspond to, calculated the values relative to the left axis that correspond to these pixel values, and then added the DLine so it is now relative to the left axis scale:

Code: Select all

    'DLine relative to the right axis
    Dim startYPix, endYPix As Integer
    Dim startYVal, endYVal As Double
    TChart1.Environment.InternalRepaint
    With TChart1.Axis.Right
      startYPix = .CalcYPosValue(12000)
      endYPix = .CalcYPosValue(16000)
    End With
    With TChart1.Axis.Left
      startYVal = .CalcPosPoint(startYPix)
      endYVal = .CalcPosPoint(endYPix)
    End With
    
    With TChart1.Tools.Items(dline(1)).asDrawLine
        '.AddLine 620, 12000, 820, 16000
        .AddLine 620, startYVal, 820, endYVal
        .Pen.Color = vbMagenta
    End With
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

tirby
Newbie
Newbie
Posts: 84
Joined: Mon Mar 16, 2009 12:00 am

Re: DLine Axis Assignment Reference issue

Post by tirby » Mon Jun 10, 2013 2:01 pm

Thanks Yeray,

I added/changed my code using the code you provided.
Now when both Series0 and Series1 are active, I see both DLines.
If I disable only Series1, both DLines remain visible.
If I disable only Series0, both DLines disappear. <<<<<Problem
If I disable both Series, both DLines are visible.
Note that when Series0 is disabled, and Series1 is enabled, both DLines are not visible. I suspect they are simply off scale.

I know I can change the visible property at any time, however, the DLines still need to be in the correct location regardless of whether or not any/either Series is active.

My real project will offer the user the option of selecting up to 8 traces, and can assign either left or right axis to each individual Trace. The user can also select to display any combination of the 8 traces, including all 8. He may well display 1 left Axis, and the remaining Right axis traces, or only left axis plots, or only right axis plots.
Through logic, the visibility of a DLine associated with a specific Trace will be controlled based on the Trace's active property.
All of the above options are subject to the operators discretion, and at any time before and/or after the DLine(s) are created.

Regards...

Yeray
Site Admin
Site Admin
Posts: 9587
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: DLine Axis Assignment Reference issue

Post by Yeray » Mon Jun 10, 2013 3:07 pm

Hi tirby,

All this customization will probably make the usage of the DrawLine tool here more complicate than drawing manually to the canvas.
This should cover the possibilities you describe without having to do further calculations each time the user changes a series visibility or a series axis.

Code: Select all

Private Sub TChart1_OnAfterDraw()
  Dim startYPix, endYPix, startXPix, endXPix As Integer
  
  If TChart1.Series(0).Active Then
    With TChart1.Series(0)
      startXPix = .CalcXPosValue(300)
      endXPix = .CalcXPosValue(500)
      startYPix = .CalcYPosValue(12)
      endYPix = .CalcYPosValue(18)
    End With
    With TChart1.Canvas
      .Pen.Color = vbCyan
      .Line startXPix, startYPix, endXPix, endYPix
    End With
  End If
  
  If TChart1.Series(1).Active Then
    With TChart1.Series(1)
      startXPix = .CalcXPosValue(620)
      endXPix = .CalcXPosValue(820)
      startYPix = .CalcYPosValue(12000)
      endYPix = .CalcYPosValue(16000)
    End With
    With TChart1.Canvas
      .Pen.Color = vbMagenta
      .Line startXPix, startYPix, endXPix, endYPix
    End With
  End If
End Sub
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

tirby
Newbie
Newbie
Posts: 84
Joined: Mon Mar 16, 2009 12:00 am

Re: DLine Axis Assignment Reference issue

Post by tirby » Mon Jun 10, 2013 3:43 pm

Yeray,

Yes, Thankyou - That's what I need to happen.
A few questions:

1. How do I get an Index reference to the Line(s) drawn on the canvas?
There will be several Lines associated with each trace at points selected by the user.

2. I need to place a Rectangle at the top end of each of those lines.
Do I still use a Rectangle Tool?
I need to populate it with text as well as control the forecolors and backcolors.

3. How do I reference the top end of the line to the middle (Y) of the bottom of the retangle, now that the lines reside on the canvas?

tirby
Newbie
Newbie
Posts: 84
Joined: Mon Mar 16, 2009 12:00 am

Re: DLine Axis Assignment Reference issue

Post by tirby » Mon Jun 10, 2013 6:14 pm

Yeray,

Over the past several weeks, my posts/questions have all been about how to accomplish one end result. As each aspect of the development revealed it’s issues, I have to incorporate the changes without changing the code that does work. (Sounds easier than it is!)
I’m using Line Series, Rectangle Tool, and since our last communication the Canvas.Line as opposed to the DLine tool.
Please review this write-up and see if in your opinion, I’m utilizing the best approaches and tools for the task at hand.

In reference to posts in this thread, the changes must follow the setups or parameters I've tried to explain in the attached document.

Thanks
Attachments
Graph.Zip
Contains Screen shots and documentation.
(154.24 KiB) Downloaded 1186 times

tirby
Newbie
Newbie
Posts: 84
Joined: Mon Mar 16, 2009 12:00 am

Re: DLine Axis Assignment Reference issue

Post by tirby » Mon Jun 17, 2013 5:45 pm

Really looking for an answer to my post dated: 10 Jun 2013 15:43

Can anyone help?

Yeray
Site Admin
Site Admin
Posts: 9587
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: DLine Axis Assignment Reference issue

Post by Yeray » Tue Jun 18, 2013 8:39 am

Hello,

Excuse us for the delayed reply here. We haven't forgotten it and we'll study it asap, but note this isn't a punctual doubt that can be reviewed easily.
You may be interested on the ProSupport subscription.
http://steema.com/licensing/support/?st ... ng_support
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Yeray
Site Admin
Site Admin
Posts: 9587
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: DLine Axis Assignment Reference issue

Post by Yeray » Tue Jun 18, 2013 11:14 am

Hello again,

I've been playing for a while with your application and I think I reached a behaviour similar to what you are trying to achieve.
I ended using Rectangle tools, since they already can show an arrow to any point you wish, in pixels.
I'm using some global arrays to store the start point of the arrows that are actually an index of the series (markStartIndex) and another array to store the position of the rectangle tool. The end point of the arrow is internally calculated, relative to the position of the rectangle tool and the start point of the arrow.

Code: Select all

Dim markEndPos(2) As TeePoint2D
Dim markStartIndex(2) As Integer
Dim draggingRect As Integer

Private Sub Command1_Click(Index As Integer)
    TChart1.Series(Index).Active = Not TChart1.Series(Index).Active
    TChart1.Tools.Items(Index).Active = Not TChart1.Tools.Items(Index).Active
    Select Case TChart1.Series(Index).Active
        Case False
            Label1(Index).Caption = "Disabled"
        Case True
            Label1(Index).Caption = "Enabled"
    End Select
End Sub

Private Sub Command2_Click(Index As Integer)
  With TChart1.Tools.Items(Index).asRectangle
    .AllowDrag = Not .AllowDrag
    Select Case .AllowDrag
        Case True
            Label2(Index).Caption = "UnPined"
        Case False
            Label2(Index).Caption = "Pined"
    End Select
  End With
End Sub

Private Sub Form_Load()
Dim dline(2) As Integer

    TChart1.Series(0).Title = "My series 0"
    TChart1.Series(0).AddXY 0, 0, "", vbBlue
    TChart1.Series(0).AddXY 100, 10, "", vbBlue
    TChart1.Series(0).AddXY 300, 12, "", vbBlue
    TChart1.Series(0).AddXY 600, 8, "", vbBlue
    TChart1.Series(0).AddXY 1200, 16, "", vbBlue
    TChart1.Series(0).AddXY 3600, 22, "", vbBlue
    
    TChart1.Series(1).Title = "My series 1"
    TChart1.Series(1).AddXY 0, 0, "", vbRed
    TChart1.Series(1).AddXY 120, 2000, "", vbRed
    TChart1.Series(1).AddXY 320, 6000, "", vbRed
    TChart1.Series(1).AddXY 620, 12000, "", vbRed
    TChart1.Series(1).AddXY 1220, 1000, "", vbRed
    TChart1.Series(1).AddXY 3600, 2700, "", vbRed
    
    Label1(0).Caption = "Enabled"
    Label1(1).Caption = "Enabled"
    Label2(0).Caption = "Pined"
    Label2(1).Caption = "UnPined"
    
    TChart1.Environment.InternalRepaint
    TChart1.Tools.Add tcRectangle
    With TChart1.Tools.Items(0).asRectangle
      .AutoSize = True
      .Text = TChart1.Series(0).Title
      .AllowResize = False
      .AllowDrag = False
      .Callout.Arrow.Visible = True
      .Callout.Arrow.Color = vbCyan
      
      markStartIndex(0) = 2
      markEndPos(0).X = 500
      markEndPos(0).Y = 18
    End With
    
    TChart1.Tools.Add tcRectangle
    With TChart1.Tools.Items(1).asRectangle
      .AutoSize = True
      .Text = TChart1.Series(1).Title
      .AllowResize = False
      .AllowDrag = True
      .Callout.Arrow.Visible = True
      .Callout.Arrow.Color = vbMagenta
      
      markStartIndex(1) = 3
      markEndPos(1).X = 820
      markEndPos(1).Y = 16000
    End With
    
    draggingRect = -1
    recalcPositions
End Sub

Private Sub recalcPositions()
  Dim startYPix, endYPix, startXPix, endXPix As Integer
 
  TChart1.Repaint
  
  If TChart1.Series(0).Active Then
    With TChart1.Series(0)
      startXPix = .CalcXPos(markStartIndex(0))
      endXPix = .CalcXPosValue(markEndPos(0).X)
      startYPix = .CalcYPos(markStartIndex(0))
      endYPix = .CalcYPosValue(markEndPos(0).Y)
    End With
    With TChart1.Tools.Items(0).asRectangle
      .Callout.XPosition = startXPix
      .Callout.YPosition = startYPix
      .Left = endXPix
      .Top = endYPix
    End With
  End If
  
  If TChart1.Series(1).Active Then
    With TChart1.Series(1)
      startXPix = .CalcXPos(markStartIndex(1))
      endXPix = .CalcXPosValue(markEndPos(1).X)
      startYPix = .CalcYPos(markStartIndex(1))
      endYPix = .CalcYPosValue(markEndPos(1).Y)
    End With
    With TChart1.Tools.Items(1).asRectangle
      .Callout.XPosition = startXPix
      .Callout.YPosition = startYPix
      .Left = endXPix
      .Top = endYPix
    End With
  End If
End Sub

Private Sub TChart1_OnRectangleToolClick(ByVal Button As TeeChart.EMouseButton, ByVal Shift As TeeChart.EShiftState, ByVal X As Long, ByVal Y As Long)
  Dim i As Integer
  For i = 0 To TChart1.Tools.Count - 1
    If TChart1.Tools.Items(i).ToolType = tcRectangle Then
      If TChart1.Tools.Items(i).asRectangle.Clicked(X, Y) Then
        draggingRect = i
      End If
    End If
  Next i
End Sub

Private Sub TChart1_OnRectangleToolDragged()
  draggingRect = -1
End Sub

Private Sub TChart1_OnRectangleToolDragging()
  If draggingRect > -1 Then
    With TChart1.Tools.Items(draggingRect).asRectangle
      If TChart1.Series(draggingRect).HorizontalAxis = aBottomAxis Or _
         TChart1.Series(draggingRect).HorizontalAxis = aBothHorizAxis Then
        markEndPos(draggingRect).X = TChart1.Axis.Bottom.CalcPosPoint(.Left)
      Else
        If TChart1.Series(draggingRect).HorizontalAxis = aTopAxis Then
          markEndPos(draggingRect).X = TChart1.Axis.Top.CalcPosPoint(.Left)
        End If
      End If
      If TChart1.Series(draggingRect).VerticalAxis = aLeftAxis Or _
         TChart1.Series(draggingRect).VerticalAxis = aBothVertAxis Then
        markEndPos(draggingRect).Y = TChart1.Axis.Left.CalcPosPoint(.Top)
      Else
        If TChart1.Series(draggingRect).VerticalAxis = aRightAxis Then
          markEndPos(draggingRect).Y = TChart1.Axis.Right.CalcPosPoint(.Top)
        End If
      End If
    End With
  End If
End Sub

Private Sub TChart1_OnScroll()
  recalcPositions
End Sub

Private Sub TChart1_OnUndoZoom()
  recalcPositions
End Sub

Private Sub TChart1_OnZoom()
  recalcPositions
End Sub
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

tirby
Newbie
Newbie
Posts: 16
Joined: Wed Oct 13, 2004 4:00 am

Re: DLine Axis Assignment Reference issue

Post by tirby » Thu Jun 20, 2013 3:33 am

Yeray,
Thanks for all your help!

I started a new test project using the code you posted on Tuesday, June 18, 2013.
I see that you are using markStartIndex(x) to point to which data point to use in calculating the X-Y for the Rectangle and Arrow.
This method doesn’t work within the parameters of the project.
The user will select a point on the Line that may or may not be on an actual data point.

Example: Using Series1, there are 2 points,
X=620/Y=12000 >>>> 4th Data Point
X=1220/Y=1000 >>>> 5th Data Point
The user may click on the plotted line at X=1000/Y=5000.

This is the exact XY point where the Retangle.Callout.XPosition needs to start at.
The endXPix of the Arrow needs to terminate 20 Pixels to the right of the Retangle.Callout.XPosition
The endYPix of the Arrow needs to terminate -50 pixels above the Rectangle.Callout.YPosition.
At these 2 endpoints is the bottom of the Rectangle tool.

I have tried several combinations of the CalcXPos(), CalcYPos(), CalcXPosValue(), CalcYPosValue(), Left and Right Axis, etc.
None of these functions return the correct Pixel values.
I tried using the TChart1.Environment.InternalRepaint as well with no success.

As I stated above, I have taken the latest code and started a test project.
I have modified it to work the way it needs to work within my actual project.
There are several other issues I need to resolve, but I believe they are related to this issue.

Again, I do appreciate your assistance, and please forgive me my tone of urgency.
I have a lot of work to complete in a very, very short period of time.

Thanks!
Attachments
DLineTest1.Zip
DLineTest1 project & Notes
(15.69 KiB) Downloaded 1186 times

Yeray
Site Admin
Site Admin
Posts: 9587
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: DLine Axis Assignment Reference issue

Post by Yeray » Thu Jun 20, 2013 3:10 pm

Hi,

Excuse me, the code from 18th June was just a modification taking your initial project as base. However, I forgot I also added two buttons and two labels, making necessary to upload the full project again. Here it is:
DLineTest.zip
(4.27 KiB) Downloaded 1196 times
I will take a look at the new version of the project and the notes you attached on 20th June asap.

In the meanwhile, please take a look at what I did in the project above. As you've noticed, I used markStartIndex() to store the start point of each draw line. Of course this was just an example that may not adjust your needs, but if you understand it I don't think it shouldn't be difficult to adapt it to your needs. Concretely, if you don't want to use markStartIndex storing the series index related to the draw line tool because you don't want such a relation, you can create two arrays (ie markStartPos(2) as TeePoint2D) similar to the markEndPos array I used to store the end positions of the tools.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

tirby
Newbie
Newbie
Posts: 16
Joined: Wed Oct 13, 2004 4:00 am

Re: DLine Axis Assignment Reference issue

Post by tirby » Sat Jun 22, 2013 2:22 pm

Yeray,
Thank you for looking at this project/issue.

I downloaded the project you modified with the addition of the 2 buttons and 2 labels.I also reviewed and made the modifications you suggested.

In General:
Added:

Code: Select all

Dim markStartPos(2) As TeePoint2D
In Form_Load(), added:

Code: Select all

markStartPos(0).X = 700
markStartPos(0).Y = 9.345
In recalcPositions():
Added/modified:

Code: Select all

startXPix = .CalcXPosValue(markStartPos(0).X)  '.CalcXPos(markStartIndex(0))
startYPix = .CalcYPosValue(markStartPos(0).Y)  '.CalcYPos(markStartIndex(0))
In evaluating the results by examining where on the plotted line the Arrow starts, I find it does not start at the points specified in the Form_Load() proceedure. By "Zooming" in you can see that the Y point is several points away from the correct position.

Also, if you try to "Zoom" more than about 3 times, an overflow error occurs.

Graciously awaiting your reply...

Yeray
Site Admin
Site Admin
Posts: 9587
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: DLine Axis Assignment Reference issue

Post by Yeray » Wed Jun 26, 2013 8:37 am

Hi,

TeePoint2D is an (X,Y) pair of Integer. That's why there seems to be a rounding problem. I've changed:

Code: Select all

Dim markStartPos(2) As TeePoint2D
Dim markEndPos(2) As TeePoint2D
For:

Code: Select all

Dim markStartPos(2, 2) As Double
Dim markEndPos(2, 2) As Double
And it works fine now. Note I've also changed the usages of markStartPos(0).X for markStartPos(0, 0), markStartPos(0).Y for markStartPos(0, 1), etc
DLineTest.zip
(4.29 KiB) Downloaded 1226 times
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

tirby
Newbie
Newbie
Posts: 16
Joined: Wed Oct 13, 2004 4:00 am

Re: DLine Axis Assignment Reference issue

Post by tirby » Thu Jun 27, 2013 2:28 am

Yeray,
Thanks so much! That solved the problem.

And as for the "Overflow" error when zooming - In recalcPositions(),
I changed the 4 startX-Y, endX-Y from integers to doubles.

Thanks again!

Post Reply