ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  X-Axis Auto Indents - Can't stop it
Posted by Mike Cotrone on Jul-25-2016 23:32
Attachments:
Hi,

I am seeing auto-indent behaviour only on the first x-axis plot. Am I doing something Wrong?

// SETUP X-AXIS
  Call c.xAxis.setLabelStyle("HelveticaNeueDeskInterface.ttc", 8*f)
  c.xAxis.setAutoScale(.2, .2)
  Call c.xAxis.SetColors(c.kTransparent)
  Call c.xAxis.setOffset(0, 4)
  Call c.xAxis.setIndent(False)
  Call c.xAxis.setRounding(True, True)
  Call c.xAxis.setMinTickInc(1)

Thank you in advance.

Mike
mwc.png

  Re: X-Axis Auto Indents - Can't stop it
Posted by Mike Cotrone on Jul-26-2016 00:03
Also to add I am using the CDXYChart.

Thanks

  Re: X-Axis Auto Indents - Can't stop it
Posted by Mike Cotrone on Jul-26-2016 00:08
With CDAreaLayer

  Re: X-Axis Auto Indents - Can't stop it
Posted by Mike Cotrone on Jul-26-2016 00:17
And Creating the ImageMap:

imageMap = c.getHTMLImageMap("lineGraph.py", "", "x={x}&xLabel={xLabel}&dataSet={dataSet}&dataSetName={dataSetName}&value={value}&field0={field0}")

  Re: X-Axis Auto Indents - Can't stop it
Posted by Peter Kwan on Jul-26-2016 01:17
Hi Mike,

Sorry, I am not sure what is the issue by reading message. In your chart, the x-axis does not seem to be indented.

In your post, I saw a line of text that says "2.0 - 3.0 sec .... 0.015ms". As I do not have your code, I am not sure how you handle that line of text. From your chart, it appears your code assumes that means x=2 and y=0.015 (and ignore the 3.0 sec part).

You mentioned you have an image map. The image map for an area chart is for the "area". Note that an "area" is not a single point. It is a region in the chart. Consider the above point x=2 and y=0.015. The area is the region between x=1.5 (as the previous point seems to be at x=1 in your chart), and ends at x=2.5. For the first point at x=0, because there is no region to the left of the point, so the area for that point is from x=0 to x=0.5.

In your chart, I also see a box appear at x=0.5. As I do not have your code, I do not know what you plot this box. Are you using x=0.5 to plot this box, or are you using the image map (which is for a region, not a single point)?

Regards
Peter Kwan

  Re: X-Axis Auto Indents - Can't stop it
Posted by Mike Cotrone on Jul-26-2016 02:07
Thanks for the reply Peter.

The .5 should be at 0 and not .5. The coordinates are some how giving me a .5 nudge on just the first plot entry. I don't know what is causing this as the coordinates in the image map are identical to the .5.

Here is my GraphDrawing Function from Xojo.
Using the auto x-axis numbering plus your labelStyle it looks proper and it scales well automatically. My last issue is just the first entry every time shows up as a "half" vs. 0 (1 with the LabelStyle).

Sorry for the beginner questions :)


  // SET MARKERS FOR GRAPH ALIGNMENT
  offsetX_OvalOutline = 5
  offsetY_OvalOutline = 5
  offsetX_OvalFill = 7
  offsetY_OvalFill = 7
  offsetX_Label = 2
  offsetY_Label = 6
  offsetX_vLine1 = 9
  offsetX_vLine2 = 9
  offsetY_vLine1 = 15
  offsetY_vLine2 = 292

  Dim f, i As Integer
  If ScalingFactor > 1 Then
    f = 2
  Else
    f = 1
  End If

  // SETUP GRAPH PLOT AREA
  Dim c As New CDXYChartMBS(Me.Width*f, Me.Height*f, &hffffff, -1, 0)
  Call c.setPlotArea(49*f, 40*f, (Me.Width-69)*f, (Me.Height-100)*f, &hffffff, c.kTransparent,  &hffffff, &hcccccc, c.kTransparent)
  Call c.SetAntiAlias(True, 1)

  // DRAW TOP LINE
  call c.addLine(50*f, 40*f, (Me.Width-20)*f, 40*f, &hcccccc, 1)
  // DRAW BOTTOM LINE
  call c.addLine(50*f, (Me.Height-60)*f, (Me.Width-20)*f, (Me.Height-60)*f, &hcccccc, 1)

  // SETUP X-AXIS
  Call c.xAxis.setLabelStyle("HelveticaNeueDeskInterface.ttc", 8*f)
  c.xAxis.setAutoScale(.2, .2)
  Call c.xAxis.SetColors(c.kTransparent)
  Call c.xAxis.setMargin(0, 5)
  Call c.xAxis.setIndent(False)
  Call c.xAxis.setRounding(True, True)
  Call c.xAxis.setMinTickInc(1)
  Call c.xAxis.setLabelFormat("{={value}+1}")

  // SETUP Y-AXIS LEFT
  Call c.yAxis.SetColors(-1)
  c.yAxis.setAutoScale(.2, .2, 0)
  Call c.yAxis.setIndent(False)
  Call c.yAxis.setLabelStyle("HelveticaNeueDeskInterface.ttc", 8*f)
  Call c.yAxis.setOffset(-4,0)

  // WRITE DATA TO GRAPH
  for i = 0 to udpSessionGraphDataClassArray.Ubound
    //SET X-AXIS LABELS FOR IPERF TIME SLOTS
    //Call c.xAxis.setLabels(udpSessionGraphDataClassArray(i).labelX)

    // ONLY DRAW SELECTED LAYERS
    If udpSessionGraphDataClassArray(i).contextualMenuChecked = False Then Continue

    // Y-AXIS LEFT
    Dim throughputDataArray() as Double
    If isServerUDP = True Then
      // IF SERVER GRAPH UDP LATENCY
      throughputDataArray() = udpSessionGraphDataClassArray(i).jitterMS()
    Else
      // IF CLIENT GRAPH UDP BITRATE :(
      throughputDataArray() = udpSessionGraphDataClassArray(i).transmittedBitsPerSecond()
    End If

    Dim thisFillColor as Integer = udpSessionGraphDataClassArray(i).colorFill
    Dim thisBorderColor as Integer= udpSessionGraphDataClassArray(i).colorBorder

    Dim leftYLayer As CDAreaLayerMBS
    leftYLayer = c.addAreaLayer
    leftYLayer.addDataSet(throughputDataArray).setDataColor(thisFillColor, thisBorderColor)
    leftYLayer.setLineWidth(1)

  next p

  // CREATE EXTRA FIELD TO MAP THE SESSION ID DURING GRAPH CANVAS MOUSE OVER
  Dim thisSessionID as String = udpSessionGraphDataClassArray(i).sessionID
  Dim extraFieldString() as String
  Dim thisArray() as Double = udpSessionGraphDataClassArray(i).transmittedBitsPerSecond()

  for d as Integer = 0 to thisArray.Ubound
    extraFieldString.Append thisSessionID
  next d
  leftYLayer.addExtraField(extraFieldString())

  next i

  // CREATE THE IMAGE MAP FOR DYNAMIC X/Y POINT REFERENCE
  If ScalingFactor > 1 Then
    Graph_Picture2x = c.makeChartPicture
    imageMap = c.getHTMLImageMap("lineGraph.py", "", "x={x}&xLabel={xLabel}&dataSet={dataSet}&dataSetName={dataSetName}&value={value}&field0={field0}")

  Else
    Graph_Picture = c.makeChartPicture
    imageMap = c.getHTMLImageMap("lineGraph.py", "", "x={x}&xLabel={xLabel}&dataSet={dataSet}&dataSetName={dataSetName}&value={value}&field0={field0}")
  End If
  Self.Invalidate(False)

  Re: X-Axis Auto Indents - Can't stop it
Posted by Mike Cotrone on Jul-26-2016 02:10
Attachments:
Sorry and I just realized I gave you the screen shot not showing that value. My bad. Here it is.
mwc.png

  Re: X-Axis Auto Indents - Can't stop it
Posted by Mike Cotrone on Jul-26-2016 02:26
Just to note for completeness -- The remainder of all y-axis values show up perfectly on the x-axis as intended. Its just the first one that is value indenting by .5.

Thanks!

  Re: X-Axis Auto Indents - Can't stop it
Posted by Mike Cotrone on Jul-26-2016 02:29
Attachments:
Example of how the other values are spot on.
Untitled.png

  Re: X-Axis Auto Indents - Can't stop it
Posted by Mike Cotrone on Jul-26-2016 02:30
Attachments:
Last example perfect for remaining plot values.
Untitled.png

  Re: X-Axis Auto Indents - Can't stop it
Posted by Peter Kwan on Jul-26-2016 03:29
Hi Mike,

I cannot find the code which draws the "mouse tracking label", which is the part that has the issue. I would imagine the code would draw a vertical line, a circle and a rectangle with text inside, but I am not sure where is the code.

In particular, I am not sure how you obtain the coordinates of the circle. Are you inferring that from the image map? As explain in my last message, the image map is not a point, but a region. The region is a polygon with multiple points as the vertices. I am not sure how the code infers a single point from the polygon. Also, the image map of the first point is different, as it does not have a left side. Is it possible to code that tries to infer a single point from the polygon cannot handle the first point correctly?

If I were to write the code, I would obtain the coordinates using XYChart.getXCoor and XYChart.getYCoor, not from the image map.

If you need further help, is it possible to inform me which part of the code is drawing the "mouse tracking label"?

Regards
Peter Kwan

  Re: X-Axis Auto Indents - Can't stop it
Posted by Mike Cotrone on Jul-26-2016 03:30
Here is my mouseMove event Code. Please let me know if you need additional function code also. Thank you so much.


  #Pragma DisableBackgroundTasks
  #Pragma DisableBoundsChecking


  Try
    Dim i as Integer

    // PREPARE IMAGEMAP PARSING PATTERNS
    Dim coordinatesPattern as String =  "(?<=,)d+,d+(?="")"
    Dim xDataValuePattern as String = "(?<=dataSetName=&value=).+(?=&field)"
    Dim iperfSessionIDPattern as String = "(?<=&field0=).+(?=.href)"

    // CAST DYNAMICALLY GENERATED IMAGE MAP
    Dim thisContent as String = Graphing_Container.imageMap

    // PARSE IMAGE MAP FOR DISPLAY DETAILS
    theCoordArray() = Common_Module.regExParseCoordinates(coordinatesPattern, thisContent)

    If Me.ScalingFactor > 0 Then
      // DIVIDE ALL ENTRIES BY 2 FOR RETINA
      theCoordArray() = retinaFY(theCoordArray())
    End If

    theValueArray() = Common_Module.regExParseValues(xDataValuePattern, thisContent, True)
    theIperfSessionArray() = Common_Module.regExParseValues(iperfSessionIDPattern, thisContent, False)

    // UDP OR TCP SERVER
    Dim transportType as String
    If iPerfToolContainerControl(Window).iPerfServerContainer1.RadioButtonTCP.Value = True Then
      transportType =  "TCP"
    Elseif iPerfToolContainerControl(Window).iPerfServerContainer1.RadioButtonUDP.Value = True Then
      transportType = "UDP"
    End If


    If theCoordArray.Ubound  <> -1 Then
      For i = 0 to theCoordArray.Ubound


        // BUILD X/Y LOC POINTS
        Dim thisPointArray() as String = Split(theCoordArray(i), ",")
        Dim chartXPos as Integer
        Dim chartYPos as Integer
        If thisPointArray.Ubound <> -1 Then
          chartXPos = CDbl(thisPointArray(0))
          chartYPos = CDbl(thisPointArray(1))
        End If

        Dim thisChartXRight as Integer = chartXPos+15
        Dim thisChartXLeft as Integer = chartXPos-15

        Dim thisChartYTop as Integer = chartYPos - 30
        Dim thisChartYBottom as Integer = chartYPos + 65

        If X <= thisChartXRight AND X>= thisChartXLeft AND Y >= thisChartYTop AND Y <= thisChartYBottom Then
          Dim thisUnit as String
          If selectedUnitType = "BPS" Then
            thisUnit = Trim(bitRateFormat.Right(5))
          Elseif selectedUnitType = "BYTES" Then
            thisUnit = Trim(transferRateFormat.Right(6))
          End If

          Me.MouseCursor = System.Cursors.FingerPointer

          Dim thisVal as String = theValueArray(i)
          Dim thisPoint as New REALbasic.Point(chartXPos-10, chartYPos-10)
          Graphing_Container.drawMarkerPoint = thisPoint


          Select Case transportType
          Case "TCP"
            Graphing_Container.drawMarkerLabel = thisVal +  " " + thisUnit
            Graphing_Container.drawSessionLabel = theIperfSessionArray(i)
            Dim sessionID as String = theIperfSessionArray(i)

          Case "UDP"
            Graphing_Container.drawMarkerLabel = thisVal +  " ms"
            Graphing_Container.drawSessionLabel = theIperfSessionArray(i)
            Dim sessionID as String = theIperfSessionArray(i)
            Dim thisUDP_Info_Array() as udpClassBasedGraphData = Graphing_Container.udpSessionGraphDataClassArray()

            // LOAD OTHER UDP DATA
            Dim xx, gg as Integer
            for xx = 0 to thisUDP_Info_Array.Ubound
              if thisUDP_Info_Array(xx).sessionID = sessionID Then
                for gg = 0 to thisUDP_Info_Array(xx).percentDatagramsLost.Ubound
                  Graphing_Container.drawLostPerc = Str(thisUDP_Info_Array(xx).percentDatagramsLost(gg))
                  Exit
                next gg
              end if
            next xx
          End Select


          Graphing_Container.drawMarker = True
          Graphing_Container.Refresh(False)
          exit sub

        Else
          Me.MouseCursor = System.Cursors.StandardPointer
          Graphing_Container.drawMarker = False

        End If

      Next i
    End If


  Catch

  End Try

  Re: X-Axis Auto Indents - Can't stop it
Posted by Mike Cotrone on Jul-26-2016 03:32
This is my paint event where I draw the marker overlays.


  Declare Sub CGContextSaveGState Lib "Cocoa" ( context As Integer )
  Declare Sub CGContextSetInterpolationQuality Lib "Cocoa" ( context As Integer, quality As Integer )
  Declare Sub CGContextRestoreGState Lib "Cocoa" ( context As Integer )
  Dim CGContextRef As Integer = g.handle( g.HandleTypeCGContextRef )
  CGContextSaveGState CGContextRef
  CGContextSetInterpolationQuality CGContextRef, 3
  g.AntiAlias = True
  Dim f as Integer

  If ScalingFactor > 1 Then
    If Graph_Picture2x <> Nil Then
      f = 2
      g.DrawPicture(Graph_Picture2x, 0, 0,g.Width,g.Height,0,0,Graph_Picture2x.Width, Graph_Picture2x.Height)
    End If
  Else
    f = 1
    g.DrawPicture(Graph_Picture, 0, 0)
  End If

  // DRAW BORDER
  g.PenHeight = 1
  g.PenWidth = 1
  g.ForeColor = &cB9B6A9
  g.DrawRect(0,0,me.Width,me.Height)



  if drawMarker = True Then
    // DRAW MARKER BALL
    g.ForeColor = &c1a4157
    g.PenHeight = 2
    g.PenWidth = 2
    Dim ovalO_XPOS as Integer = (drawMarkerPoint.X + offsetX_OvalOutline)
    Dim ovalO_YPOS as Integer =  (drawMarkerPoint.Y + offsetY_OvalOutline)
    g.DrawOval(ovalO_XPOS, ovalO_YPOS, 10,10)
    g.ForeColor = &cC7EAFF
    Dim ovalF_XPOS as Integer = (drawMarkerPoint.X + offsetX_OvalFill)
    Dim ovalF_YPOS as Integer = (drawMarkerPoint.Y + offsetY_OvalFill)
    g.FillOval(ovalF_XPOS, ovalF_YPOS,6,6)

    // DRAW MARKER LABEL
    g.PenHeight = 1
    g.PenWidth = 1

    g.ForeColor = &c1a4157
    g.TextSize = 10
    g.TextFont = "System"

    // SET BOOL FOR UDP
    Dim drawUDPBool as Boolean
    If drawLostPerc <> "" or isServerUDP = True Then
      drawUDPBool = True
    end if

    // CREATE LABEL STRING 1/2/3
    Dim theString1 as String = "Session: "+drawSessionLabel
    Dim theString2 as String
    Dim theString3 as String
    Dim theLabelwidth as Double
    Dim theLabelheight as Integer

    If drawUDPBool = True Then
      // UDP
      theString2 = "Latency: "+ drawMarkerLabel
      theString3 = "Lost frames: " + drawLostPerc
      // SIZE THE W/H FOR THE LABEL
      theLabelwidth = g.StringWidth(theString2)
      theLabelheight = g.StringHeight(theString2, 1500)*3

    Else
      // TCP
      theString2 = " " +drawMarkerLabel
      // SIZE THE W/H FOR THE LABEL
      theLabelwidth = g.StringWidth(theString2)
      theLabelheight = g.StringHeight(theString2, 1500)*2
    end if

    // LABEL DETECTION SO LABEL DOESN'T GO OFF SCREEN
    Dim theLabelXpos as Integer =  (drawMarkerPoint.X + offsetX_Label) - (theLabelwidth/2)
    Dim theLabelYpos as Integer =  drawMarkerPoint.Y - offsetY_Label
    Dim myContainerW as Integer = Self.Width
    Dim labelW as Integer = theLabelXpos + theLabelwidth
    Dim theLabelRectXpos as Integer = theLabelXpos-6
    Dim theLabelRectYpos as Integer = theLabelYpos-theLabelheight
    Dim theLabelRectW as Integer = theLabelwidth+9
    Dim theLabelRectH as Integer = theLabelheight+5

    Dim OOB as Integer = detectOutOfBounds(theLabelRectXpos, theLabelRectW)
    If OOB = 0 Then
      // OUT OF BOUNDS LEFT SIDE
      theLabelXpos = theLabelXpos + 40
      theLabelRectXpos = theLabelRectXpos + 40

    Elseif OOB = 1 Then
      // OUT OF BOUNDS RIGHT SIDE
      theLabelXpos = theLabelXpos - 40
      theLabelRectXpos = theLabelRectXpos - 40

    end if

    // DRAW LABEL BACKGROUND
    g.ForeColor = &cFFFBE9
    Dim fillxPOS as Integer
    Dim fillyPOS as Integer
    If drawUDPBool = True Then
      fillxPOS = theLabelRectXpos + 9
      fillyPOS = theLabelRectYpos + 5
    Else
      fillxPOS = theLabelRectXpos + 9
      fillyPOS = theLabelRectYpos + 4
    end if
    Dim fillW as Integer = theLabelRectW+2
    Dim fillH as Integer = theLabelRectH
    g.FillRect(fillxPOS, fillyPOS, fillW, fillH)

    // DRAW LABEL BORDER
    g.ForeColor = &c1a4157
    Dim borderXPOS as Integer
    Dim borderYPOS as Integer
    If drawUDPBool = True Then
      borderXPOS = theLabelRectXpos + 8
      borderYPOS = theLabelRectYpos + 4
    Else
      borderXPOS = theLabelRectXpos + 8
      borderYPOS = theLabelRectYpos + 3
    end if
    Dim borderW as Integer = theLabelRectW+4
    Dim borderH as Integer = theLabelRectH + 1
    g.DrawRect(borderXPOS,borderYPOS, borderW, borderH)


    // PREPARE STRING-1 COORDINATES
    Dim string1xPOS as Integer
    Dim string1yPOS as Integer
    If drawUDPBool = True Then
      // UDP
      string1xPOS = theLabelXpos + 8
      string1yPOS = theLabelYpos - 20
    Else
      // TCP
      string1xPOS = theLabelXpos + 8
      string1yPOS = theLabelYpos - 8
    end if

    // PREPARE STRING-2 COORDINATES
    Dim string2xPOS as Integer = string1xPOS
    Dim string2yPOS as Integer = string1yPOS + 12
    // PREPARE STRING-3 COORDINATES
    Dim string3xPOS as Integer = string2xPOS
    Dim string3yPOS as Integer = string2yPOS + 12

    // DRAW STRINGS INSIDE OF LABEL
    g.ForeColor = &c000000
    g.DrawString(theString1, string1xPOS, string1yPOS)
    g.DrawString(theString2, string2xPOS, string2yPOS)
    g.DrawString(theString3, string3xPOS, string3yPOS)

    // UDP HOUSEKEEPING
    drawLostPerc = ""


    // DRAW VERTICAL MARKER LINE
    g.ForeColor = &cC6C6C6
    g.PenHeight = 1
    g.PenWidth = 1
    Dim vDashedLineX1Pos as Integer = (drawMarkerPoint.X+offsetX_vLine1)
    Dim vDashedLineY1Pos as Integer = (drawMarkerPoint.Y+offsetY_vLine1)
    Dim vDashedLineX2Pos as Integer = (drawMarkerPoint.X+offsetX_vLine2)
    Dim vDashedLineY2Pos as Integer = offsetY_vLine2
    g.DrawLine (vDashedLineX1Pos, vDashedLineY1Pos, vDashedLineX2Pos, vDashedLineY2Pos)
  end if



  // *********** *********** *********** //
  Dim yAxisLabelTitle, yAxis2LabelTitle as String

  // DRAW X-AXIS
  g.textsize = 12
  g.TextFont = "System"
  Dim xAxisLabelTitle as String = "Number of iPerf Reports"
  Dim xAxisLabelTitleWidth as Double = g.StringWidth(xAxisLabelTitle)
  g.ForeColor = &c1a4157
  Dim xAxisLabelTitleXPOS as Integer = (Me.Width/2) - (xAxisLabelTitleWidth/2)
  Dim xAxisLabelTitleYPOS as Integer = Me.Height - 15
  g.drawstring(xAxisLabelTitle,  xAxisLabelTitleXPOS, xAxisLabelTitleYPOS)


  // DRAW Y-AXIS LEFT TITLE FOR SERVER TCP/UDP GRAPHS
  If isServerVisible = True Then
    yAxisLabelTitle = Trim(ServerGraphBaseContainer(Window).YAxisUnitTitle)
  End If


  // DRAW Y-AXIS LEFT TITLE FOR CLIENT TCP/UDP GRAPH
  If isClientVisible = True  Then
    yAxisLabelTitle = Trim(ClientGraphBaseContainer(Window).YAxisUnitTitle)
  End If

  // DRAW Y-AXIS TITLE (LEFT)
  g.textsize = 12
  g.TextFont = "System"
  g.ForeColor = &c1a4157
  g.DrawString(yAxisLabelTitle, 10, 20)

  If graphReset = True Then
    if isServerVisible = True Then
      ServerGraphBaseContainer(Window).GraphSplash_Canvas.Visible = True
      ServerGraphBaseContainer(Window).GraphSplash_Canvas.Invalidate(False)
    Elseif isClientVisible = True Then
      ClientGraphBaseContainer(Window).GraphSplash_Canvas.Visible = True
      ClientGraphBaseContainer(Window).GraphSplash_Canvas.Invalidate(False)
    End If
  End If

  CGContextRestoreGState CGContextRef

  Re: X-Axis Auto Indents - Can't stop it
Posted by Mike Cotrone on Jul-26-2016 03:34
Yes I extracted this info from your polygon coordinates and formed an x/y position on the screen (with your help a while back:) ).

It works great except of course for the first value.

  Re: X-Axis Auto Indents - Can't stop it
Posted by Mike Cotrone on Jul-26-2016 03:35
SOrry just saw this Entry that you wrote:

"If I were to write the code, I would obtain the coordinates using XYChart.getXCoor and XYChart.getYCoor, not from the image map."


I will give this a try vs. the imageMap.

Thank you Peter.
Mike

  Re: X-Axis Auto Indents - Can't stop it
Posted by Peter Kwan on Jul-26-2016 15:14
Hi Mike,

The image map is a region. For an area chart, it contains 4 to 6 points for each data value, with each point have 2 numbers for the x and y coordinates. This forms a polygon representing the area region. You may use these coordinates to obtain the hot spot region (eg. if you want to highlight the region).

In your code, it seems to be using the last vertex. Unluckily, the last vertex is not necessarily the position of the data point. In fact, there is no guarantee which point is the data point.

If the intention is to get the data point position (as opposed to the hot spot region), the best method is to use getXCoor and getYCoor. This should be much simpler.

Regards
Peter Kwan