Page 1 of 1

Horizontal Bar charts series marks can be cut off

Posted: Mon Dec 03, 2012 5:32 pm
by 15046369
Depending on the resolution of the computer in use the horizontal bar chart can show the marks for the series values running off the edge of the chart.

This is how it shows how it looks on a high res display, which is fine
Screen shot 2012-12-03 at 17.16.18.png
Screen shot 2012-12-03 at 17.16.18.png (63.77 KiB) Viewed 7298 times
This image shows the same chart on a lower res screen, with exactly the same settings for fonts, panel margins, axis, etc.
Screen shot 2012-12-03 at 17.16.47.png
Screen shot 2012-12-03 at 17.16.47.png (57.46 KiB) Viewed 7310 times
I've looked around but can't see how to interrogate the TeeChart object to find out if the text for the marks appear off the chart area.

So my question is how to do this? I know adjusting the right margin of the panel fixes the problem, however this fixes it only for certain screen resolution/chart width/font size combinations - of which there are many. This needs to be dynamic as the width of the chart, the font used for the marks and the text in the marks are all variable.

Re: Horizontal Bar charts series marks can be cut off

Posted: Tue Dec 04, 2012 10:27 am
by yeray
Hi,

You can get the marks X position and width once the chart has been drawn. Here is how you could do it.

Code: Select all

Private Sub Form_Load() 
  TChart1.Aspect.View3D = False

  TChart1.AddSeries scHorizBar
  With TChart1.Series(0)
    .FillSampleValues
    .ColorEachPoint = True
    .Marks.Font.Size = 20
    '.Marks.Transparent = True
    .Marks.Style = smsPercent
  End With
End Sub

Private Sub TChart1_OnAfterDraw()
  Dim i, xpos, ypos As Integer
  For i = 0 To TChart1.Series(0).Count - 1
    xpos = TChart1.Series(0).Marks.Positions.Position(i).LeftTop.X
    xpos = xpos + TChart1.Series(0).Marks.Positions.Position(i).Width
    ypos = TChart1.Series(0).CalcYPos(i)
    TChart1.Canvas.Pen.Color = TChart1.Series(0).PointColor(i)
    TChart1.Canvas.DrawLine xpos, ypos, xpos, ypos + 35
    If xpos > TChart1.GetChartRect.Right Then
      TChart1.Canvas.TextOut xpos, ypos, "out"
    End If
  Next i
End Sub
However, if you set the marks to be transparent and then you want to get the position where the mark string ends, since you seem to be using smsPercent Marks Style, you'll probably have to use the OnGetSeriesMark to get the string that will be drawn, and calculate its width. Something like:

Code: Select all

Dim widths() As Integer

Private Sub Form_Load()  
  TChart1.Aspect.View3D = False

  TChart1.AddSeries scHorizBar
  With TChart1.Series(0)
    .FillSampleValues
    .ColorEachPoint = True
    .Marks.Font.Size = 20
    .Marks.Transparent = True
    .Marks.Style = smsPercent
  End With
  
  ReDim widths(TChart1.Series(0).Count) As Integer
End Sub

Private Sub TChart1_OnAfterDraw()
  Dim i, xpos, ypos As Integer
  For i = 0 To TChart1.Series(0).Count - 1
    xpos = TChart1.Series(0).Marks.Positions.Position(i).LeftTop.X
    xpos = xpos + (TChart1.Series(0).Marks.Positions.Position(i).Width / 2)
    xpos = xpos + (widths(i + 1) / 2)
    ypos = TChart1.Series(0).CalcYPos(i)
    TChart1.Canvas.Pen.Color = TChart1.Series(0).PointColor(i)
    TChart1.Canvas.DrawLine xpos, ypos, xpos, ypos + 35
    If xpos > TChart1.GetChartRect.Right Then
      TChart1.Canvas.TextOut xpos, ypos, "out"
    End If
  Next i
End Sub

Private Sub TChart1_OnGetSeriesMark(ByVal SeriesIndex As Long, ByVal ValueIndex As Long, MarkText As String)
  Dim tmpWidth, xpos, ypos As Integer
  If ValueIndex > -1 And SeriesIndex > -1 And MarkText <> "" Then
    TChart1.Canvas.Font.Size = TChart1.Series(SeriesIndex).Marks.Font.Size
    TChart1.Canvas.Font.Name = TChart1.Series(SeriesIndex).Marks.Font.Name
    widths(ValueIndex + 1) = TChart1.Canvas.TextWidth(MarkText)
  End If
End Sub