TSimpleGraph issues and suggestions

Please post bug reports, feature requests, or any question regarding the DELPHI AREA projects here.

TSimpleGraph issues and suggestions

Hi,

I have been playing with TSimpleGraph for some time and I would like to mention a few changes I have made.

1. I set "fTag: TObject;" instead of "fTag: Integer;" That way it is possible to associate graph nodes with other objects.

2. I implemented an fVAlignment property for vertical alignment of the text of a node.

3. I have made nodes "drop aware", that is, when a node is dropped over another node an event is fired and a proper event handler can be triggered.

4. There is an issue with the function TGraphNode.GetTextRect: TRect;
When zooming, at certain zoom percentages the text of a node is truncated and part of it is replaced by dots (...). I think it is related to some decimal values convetred to integers. I have quick-fixed this by setting Result.Right := MaxTextRect.Right+2; instead of conditionally calculating it.

5. There is an issue with procedure TSimpleGraph.ToggleNodesAt(const Rect: TRect; KeepOld: Boolean);
The problem is related to selecting horizontal or vertical links with a selection rectangle and the cause is the zero dy or dx, respectively. An easy workaround is to expand the bounded box of links by 1, all around.

6. Finally, I have moved some code that draws links, after code that draws nodes. That way the links are not covered by other nodes. This affects printing as well.

Thats all. I think that issues No4 and No5 affect all of us using TSimpleGraph. The other mentioned here are alterations for my own needs.

That's all. BTW, well done for this nice component.

Fotis

kokkoras
Moderator

Posts: 317
Joined: March 12th, 2005, 11:19 pm
Location: Thessaloniki, Greece

Re: TSimpleGraph issues and suggestions

kokkoras wrote:Hi,

There is an issue with the function TGraphNode.GetTextRect: TRect;
When zooming, at certain zoom percentages the text of a node is truncated and part of it is replaced by dots (...). I think it is related to some decimal values convetred to integers. I have quick-fixed this by setting Result.Right := MaxTextRect.Right+2; instead of conditionally calculating it.

Hello
I think the (...) dots depend on the text flags DT_END_ELLIPSIS set inside GraphNode.DrawText procedure

DrawTextFlags := DT_WORDBREAK or DT_NOPREFIX or DT_END_ELLIPSIS or TextAlignFlags[Alignment];

to avoid those dots you can try something like:

DT_WORDBREAK or DT_NOPREFIX or TextAlignFlags[Alignment];

to avoid text clipping:
DT_WORDBREAK or DT_NOPREFIX or DT_NOCLIP or TextAlignFlags[Alignment]

HTH
lbc
Junior Member

Posts: 48
Joined: February 4th, 2004, 7:50 am
Location: Italy

Well, my point is that, as soon as some text is fully displayd because it fits in the available node width, it should be fit in all zooming states. Having those dots is a nice feature but only when the text doesn't fit.

Fotis K.

kokkoras
Moderator

Posts: 317
Joined: March 12th, 2005, 11:19 pm
Location: Thessaloniki, Greece

Hello
ok, actually i can reproduce your point
as far as I can see, the zooming "core" is located in the WMPaint(var Msg: TWMPaint) procedure
look at:
Code: Select all
....        SetMapMode(MemDC, MM_ANISOTROPIC);        SetWindowExtEx(MemDC, 100, 100, nil);        SetViewPortExtEx(MemDC, Zoom, Zoom, nil);...

As far as the text issue it seems to me that setting the Text Margin to 0 can help a bit in keeping the same "text proportions" at all zooming states

HTH
lbc
Junior Member

Posts: 48
Joined: February 4th, 2004, 7:50 am
Location: Italy

The code

kokkoras,

are you planning to post the code ?

Serg...
sergisan
Active Member

Posts: 20
Joined: October 19th, 2005, 8:30 pm

here is the code:

Code: Select all
function TGraphNode.GetTextRect: TRect;

locate the following 2 lines of code:

Code: Select all
if Result.Right > MaxTextRect.Right then    Result.Right := MaxTextRect.Right;

and replace them with:

Code: Select all
Result.Right := MaxTextRect.Right+1;

regards

fotis

kokkoras
Moderator

Posts: 317
Joined: March 12th, 2005, 11:19 pm
Location: Thessaloniki, Greece

lbc wrote:Hello
As far as the text issue it seems to me that setting the Text Margin to 0 can help a bit in keeping the same "text proportions" at all zooming states
HTH

It's true because it gives the same result: more space for the text to fit. But the drawback is that Margin is for another usage.

fotis

kokkoras
Moderator

Posts: 317
Joined: March 12th, 2005, 11:19 pm
Location: Thessaloniki, Greece

Re: The code

sergisan wrote:kokkoras,
are you planning to post the code ?
Serg...

Do you mean the zoom issue or the truncated text issue? I have already posted the second one. I will check for the former soon.

fotis

kokkoras
Moderator

Posts: 317
Joined: March 12th, 2005, 11:19 pm
Location: Thessaloniki, Greece

ok, here is the quick fix for the "selection of horizontal and vertical links" issue - I hope its understood.

Code: Select all
procedure TSimpleGraph.ToggleNodesAt(const Rect: TRect; KeepOld: Boolean);var  GraphObject: TGraphObject;  I: Integer;  R: TRect;  myLinkRect: TRect;   //FOTIS: additional varbegin  if not KeepOld then    SelectedObjects.Clear;  for I := Objects.Count - 1 downto 0 do  begin    GraphObject := Objects[I];    // FOTIS: handle the horizontal or vertical link anomaly due to IntersectRect    if GraphObject.IsLink then begin      myLinkRect:= GraphObject.BoundsRect;      myLinkRect.Top:= myLinkRect.Top-1;      myLinkRect.Bottom:= myLinkRect.Bottom+1;      myLinkRect.Left:= myLinkRect.Left-1;      myLinkRect.Right:= myLinkRect.Right+1;      if IntersectRect(R, Rect, myLinkRect) then        GraphObject.Selected := not GraphObject.Selected;    end;    //FOTIS: handle non-Link objects    if ((not GraphObject.IsLink) and (IntersectRect(R, Rect, TGraphNode(GraphObject).BoundsRect)) )    then      GraphObject.Selected := not GraphObject.Selected;  end;end;

fotis

kokkoras
Moderator

Posts: 317
Joined: March 12th, 2005, 11:19 pm
Location: Thessaloniki, Greece

Hello
kokkoras wrote:
It's true because it gives the same result: more space for the text to fit. But the drawback is that Margin is for another usage.

fotis

yes, anyway my suggestion was to investigate if the text issue could be related in some way to the Margin calculations...

As i said the zooming "core" seems to be located in the WMPaint(var Msg: TWMPaint) procedure inside the section

SetMapMode(MemDC, MM_ANISOTROPIC);
SetWindowExtEx(MemDC, 100, 100, nil);
SetViewPortExtEx(MemDC, Zoom, Zoom, nil);

but i don't see how this section could to be corrected (if needed) to solve the text issue..

as far as the other code sections related to zoom (like the SetZoom) seem not having any issue
lbc
Junior Member

Posts: 48
Joined: February 4th, 2004, 7:50 am
Location: Italy

In my early atempts to fix the problem, I also investigated the margin value, but I abandon it as soon as I discovered that it is a fixed value, set by the user (or the default value, anyway).

Regarding the textExtend calculations, I think they come after the zoom state has been set. That's why I changed the code I mentioned in the other post. The fact that it happens at certain zoom states supports this. Anyway, I think adding a pixel width is not a big deal unless the context of use requires precision.

fotis.

kokkoras
Moderator

Posts: 317
Joined: March 12th, 2005, 11:19 pm
Location: Thessaloniki, Greece

kokkoras wrote:The fact that it happens at certain zoom states supports this. Anyway, I think adding a pixel width is not a big deal unless the context of use requires precision.

fotis.

Hello
i agreee with you
by the way have you had the chance to test with a lot of fonts, sizes, text styles etc. if your fix eliminate definitely that text issue at any zoom state?
lbc
Junior Member

Posts: 48
Joined: February 4th, 2004, 7:50 am
Location: Italy

Hello
i agreee with you
by the way have you had the chance to test with a lot of fonts, sizes, text styles etc. if your fix eliminate definitely that text issue at any zoom state?

Yes I have tested it. It works ok as soon as the node is not changed manually, in terms of width. If it does though, the problem sometimes re-appears, but this is expected due to the nature of the textExtend calculations made internally.

That is, my fix provides an initial width in which the initial text fits well, in any zoom state.

BTW, in my understanding, the textExtend function returns the space (TRect) required to display the given text in the given canvas (or DC in C++ ternimology) using the Font settings set for the canvas. Since the code under consideration is a method of TGraphNode, calculations should use the font used in that particular node. Under this perspective I can not see any other location for the problem than the internals of the textExtend function. I guess there is a usual round step somewhere instead of an Int()+1 (or Roof). For example, if the text requires 100.4 pixels width to fit then the desired integer should be 101, not 100.

fotis

kokkoras
Moderator

Posts: 317
Joined: March 12th, 2005, 11:19 pm
Location: Thessaloniki, Greece

well, thank you

just an idea: so, what about replacing the zooming section (basically currently implemented inside WMPaint by calling Windows mapping mode) with a simple for... loop inside the SetZoom procedure that just "scales" down/up all the existent nodes (ie: SimpleGraph.SelectedObjects or Objects) by a factor? So the texts sizes could be calculated there...

Of course the WMPaint is more efficient (for example i suppose it has been implemented for eliminating the flickering)
lbc
Junior Member

Posts: 48
Joined: February 4th, 2004, 7:50 am
Location: Italy

I think, I can live with the current state for the time being. I am quite bussy at the moment with other stuff.

kokkoras
Moderator

Posts: 317
Joined: March 12th, 2005, 11:19 pm
Location: Thessaloniki, Greece

Next