I'm using a chart with a serie Line, and adding some marks on it, label style. I tried to locate the marks in "auto" but at the end, some marks is always over the line.
Is there any way to locate the marks on some area where there is no curve ?
See "LP2/3" and "HP5/6" marks below, they could be under the point, but I don't know how to do it.
:
The free component Microsoft Graph was doing this, with automatic callouts with well separated marks from the points if they were too close.
******** UPDATE 21st OCTOBER 2022 ***************
I finally succeded in finding a way to avoid overlapping between marks and lines.
Here is the code I used :
Code: Select all
Private Sub modelgraph_afterdraw(sender As Object, e As Steema.TeeChart.Drawing.Graphics3DGdiPlus) Handles modelgraph.AfterDraw
Dim series_index As Integer
Dim mps As Steema.TeeChart.Styles.SeriesMarks.Position
If modelgraph.Series.Count > 0 Then
For Each s As Steema.TeeChart.Styles.Series In modelgraph.Series
series_index = modelgraph.Series.IndexOf(modelgraph.Series.WithTitle(s.Title))
' repositionning labels
If s.Marks.Positions.Count > 0 Then
With s.Marks.Positions
For i As Integer = 0 To s.Count - 1
mps = s.Marks.Positions(i)
mps.Custom = True
Do While MarkOverlaps(i, s)
With s.Marks.Positions(i)
If s(i).Label Like "*1/2*" Or s(i).Label Like "*3/4*" Then
.LeftTop.X = .LeftTop.X - 2
.LeftTop.Y = .LeftTop.Y - 2
.ArrowTo.X = .LeftTop.X + .Width / 2
.ArrowTo.Y = .LeftTop.Y + .Height
Else
.LeftTop.X = .LeftTop.X + 2
.LeftTop.Y = .LeftTop.Y + 2
.ArrowTo.X = .LeftTop.X + 2
.ArrowTo.Y = .LeftTop.Y + 2
End If
End With
Loop
Next i
End With
End If
Next
End If
End Sub
Code: Select all
Private Function MarkOverlaps(ValueIndex As Integer, s As Steema.TeeChart.Styles.Series) As Boolean
Dim i As Integer
Dim result1 As Boolean = False
Dim result2 As Boolean = False
With s.Marks.Positions
For i = 0 To s.Count - 1
If (i <> ValueIndex) Then
If s.Marks.Positions(i).Bounds.IntersectsWith(s.Marks.Positions(ValueIndex).Bounds) Then
result1 = True
Exit For
End If
End If
Next i
If (ValueIndex = 0) Then
result2 = SegmentIntersectRectangle(s.Marks.Positions(ValueIndex).Bounds, s.CalcXPos(0), s.CalcYPos(0), s.CalcXPos(1), s.CalcYPos(1))
ElseIf (ValueIndex = s.Count - 1) Then
result2 = SegmentIntersectRectangle(s.Marks.Positions(s.Count - 1).Bounds, s.CalcXPos(s.Count - 2), s.CalcYPos(s.Count - 2), s.CalcXPos(s.Count - 1), s.CalcYPos(s.Count - 1))
Else
result2 = SegmentIntersectRectangle(s.Marks.Positions(ValueIndex).Bounds, s.CalcXPos(ValueIndex - 1), s.CalcYPos(ValueIndex - 1), s.CalcXPos(ValueIndex), s.CalcYPos(ValueIndex)) _
Or SegmentIntersectRectangle(s.Marks.Positions(ValueIndex).Bounds, s.CalcXPos(ValueIndex), s.CalcYPos(ValueIndex), s.CalcXPos(ValueIndex + 1), s.CalcYPos(ValueIndex + 1))
End If
End With
Return (result1 Or result2)
End Function
- the repositionning works, but to see it i must click on the graph. It won't update the graph before I "touch it"
- after zooming on a specific area, the initial marks remain at their location, and are not displayed with the new view after zoom.
(attached 3 pictures, after alignment, after marks alignment, and after zoom)
I guess this is something very simple I miss, but I don't see....
Thanks