Solved

? upsidedown tree

Posted on 2000-04-20
19
219 Views
Last Modified: 2010-04-04
hi friends,

if there any (free) component, witch can visualize
multiple beginnings connected down to one end?
(must not look like a treeview)

meikl
0
Comment
Question by:kretzschmar
  • 11
  • 6
  • 2
19 Comments
 
LVL 9

Expert Comment

by:ITugay
ID: 2737267
Hi meikl,
Is it must visualize DB table?
-----
Igor
0
 
LVL 27

Author Comment

by:kretzschmar
ID: 2737279
hi igor,

no, yes :-)

i need this for visualizing and designing a production-flow and yes, the result is stored in a db, but what i need must not be data-aware.

you know, on the end is the endproduct, but before the product is ready must be done other jobs, which can also be paralell.
sample

J  J
|  |
J  J
|/
J
|
J  J
|/
E

i have my own, but that looks not nice enough for me, therefore before i design a new, it could be there is one, which i can use.

do you know such a component?

meikl
0
 
LVL 9

Expert Comment

by:ITugay
ID: 2737309
Hi,
I have my own data-aware, but it inherits from TDrawGrid. It was done long time ago, I hope I'm able now to remove data-aware dependance. To see how it look, I can send you screen shot of it.
----
Igor.
0
 
LVL 27

Author Comment

by:kretzschmar
ID: 2737322
yup,
would be nice.

send the shot to
meikl@spektracom.de

meikl
0
 
LVL 9

Expert Comment

by:ITugay
ID: 2737364
I just send to you my treeview and only now I get understanding that you need "upsidedown" tree. Sorry, I haven't it.
-----
Igor.
0
 
LVL 27

Author Comment

by:kretzschmar
ID: 2737392
not at all, igor,
thanks for the try,

but as i said,
it must not be a (upsidedown) treeview,
it must only be able to show the behaviour,
shown above.

waiting now
0
 
LVL 27

Author Comment

by:kretzschmar
ID: 2737421
hmm, maybe i found something at

www.melander.dk

the tstatemachine

its just a bit overdressed for my needs,
but matches my needs of designing the behaviour.

any similar suggestions?
0
 
LVL 27

Author Comment

by:kretzschmar
ID: 2737736
Adjusted points from 50 to 200
0
 
LVL 27

Author Comment

by:kretzschmar
ID: 2737737
raising points now,

found one comercial,
which may fit,

expressflowchart at
www.devexpress.com

but also overdressed

any other suggestions ?
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 9

Expert Comment

by:ITugay
ID: 2738176
Meikl,
If you will increase points so fast, I will write it for you especcialy;)))
0
 
LVL 27

Author Comment

by:kretzschmar
ID: 2738417
:-))

well, if you can give such a solution,
which will match my needs,
then i will offer 500 Pts. A graded
0
 
LVL 10

Expert Comment

by:Lischke
ID: 2743026
Hi Meikl,

here's another tree (also commercial) but is very much like what you want: www.teemach.com/products/teetree/tree%20galery.htm.

Ciao, Mike
0
 
LVL 9

Accepted Solution

by:
ITugay earned 500 total points
ID: 2743131
Hi meikl,

I thought about your tree (not for points) it's realy interesing me;) And it's seems to me I formed my opinion. It's here.

Every node of products tree must be a visual component inherited from TGraphic control. Let call it TNodeView. All TNodeView should be placed in TreeArea (TForm for ex.) Axis "X" (horizontal) of TreeArea is a time.

Every TNodeView, of course, have metrics left, top, width, height and reference to TreeItem which has properties ID_ITEM, ID_PARENT, ORDER. TreeItem is not visual, it used only for link with database table.

To place TNodeView on TTreeArea we need only calculate position and size of TNodeView. Width of TNodeView is fixed and depend from current horizontal scale factor. We must begin calculation of position from roort. Left  position of root TNodeView is quantity of subnodes levels * width. Height is maximum of (quantity of subnodes for each level) * height of one node. Top of TNodeView is calculated by it's parent and it equal Top of parent + summ of height of previous nodes in the same level.

It's all. It's seems that implementation of this algorythm is more simple then explanation;)

We will have something like this:

+-+ +-+ +-+
+-+ |  |  |  |
       |  |  |  | last
+-+ |  |  |  |  item
+-+ +-+ |  | is root.
              |  |
       +-+ |  |
       +-+ +-+

I know if tree is very comlex and large then every next TNodeView became higher and higher. But we can add vertical scale factor.

If you'd like this idea, I can make model to try.

Best regards
-----
Igor.
0
 
LVL 27

Author Comment

by:kretzschmar
ID: 2743282
hmmm, hmmm, hmmmm, hmmmm,

first thanks to mike for your suggestion, but i will avoid comercials for now.

to igor,
well, hard to understand,
could work, could not work and
i don't want that you invest time,
what could be unusual.

i will explain my thought.
i thought about to use a tshape-descending,
which provides additional a nextshape-property and a data-property
- nextshape points to a same-class shape
- data holds the id of the record

i've following recordstructure

JOBLISTJOB_ID -> PK
JOBLIST_ID -> FK NOT NULL -> Points to Joblist-table
JOB_ID -> FK NOT NULL -> Points to Job-table
NEXTJOB_ID -> FK NULL -> Points to Job-table
PREVJOBS -> Integer -> obsolete, used as indicator and "parent"jobcounter

I've following rules

PREVJOBS = 0 -> Indicates a first entry
NEXTJOB_ID = NULL -> Last Job, there can be only one record, with the same JOBLIST_ID, where this field can be null

therefore
>If you'd like this idea, I can make model to try.
i don't know, maybe

meikl
0
 
LVL 27

Author Comment

by:kretzschmar
ID: 2914639
Adjusted points from 200 to 500
0
 
LVL 27

Author Comment

by:kretzschmar
ID: 2914640
Comment accepted as answer
0
 
LVL 27

Author Comment

by:kretzschmar
ID: 2914641
its time to close this thread

igor provided me following unit:
unit treechrt;

interface

uses sysutils, classes, contnrs, controls, extctrls,
     graphics, stdctrls, dbtables;

type

   TTreeCharts = class; // forward definition

   TTreeChart  = class(TLabel)
   public
     ID         : integer;
     ID_Parent  : integer;
     Order      : integer;
     ParentView : TTreeChart;  // parent visible object (TLabel)
     ParentNode : TTreeCharts; // parent list item
   end;

   PTreeMetrics = ^TTreeMetrics;
   TTreeMetrics = record
     Width    : integer;
     Height   : integer;
     X_Indent : integer;
     Y_Indent : integer;
   end;

   TTreeCharts = class(TObjectList)
     Item        : TTreeChart;
     Parent      : TTreeCharts; // parent list item
     LastMetrics : TTreeMetrics;

     destructor  Destroy; override;
     // tree building
     procedure   Resort;
     procedure   ExtractSubNodes(L : TObjectList);
     // position calc services
     procedure   MaxSubLevels(fCur : integer; var fMax : integer);
     procedure   IncSubCount(var CNT : integer);
     procedure   SetLeft(aMetrics : PTreeMetrics; aLeft : integer);
     // position calc methods
     procedure   CalcLeft(aMetrics : PTreeMetrics);
     procedure   CalcHeight(aMetrics : PTreeMetrics);
     procedure   CalcTop(aTop : integer);
     procedure   CalcMetrics(aMetrics : PTreeMetrics);
     procedure   CalcIndent(aMetrics : PTreeMetrics);
     // set view area
     procedure   SetView(aView : TWinControl);
     // edit/delete/add methods
     function    FindItem(aItem : TTreeChart) : TTreeCharts;
     procedure   DeleteItem(aItem : TTreeChart);
     procedure   AddItem(aItem : TTreeChart);

   end;

   TTreeChartCreateProc = function(aQuery : TQuery) : TTreeChart;

const
   DefTreeMetrics : TTreeMetrics = // default visible item metrics
   (Width    : 97;
    Height   : 21;
    X_Indent : 1;
    Y_Indent : 1);


function  DefTreeItemCreate(aQuery : TQuery) : TTreeChart;
function  BuildTreeItems(aQuery : TQuery; TreeItemCreate : TTreeChartCreateProc) : TTreeCharts;

implementation

function DefTreeItemCreate(aQuery : TQuery) : TTreeChart;
begin
  // aQuery = nil for Root item
  result:=TTreeChart.Create(nil);
  if aQuery = nil
    then result.Caption:='ROOT';
  result.Cursor:=crHandPoint;
end;

function BuildTreeItems(aQuery : TQuery; TreeItemCreate : TTreeChartCreateProc) : TTreeCharts;
var L : TObjectList;
    T : TTreeChart;
begin
  L := TObjectList.Create;

  aQuery.First;
  while not aQuery.EOF do
  begin
    T:=TreeItemCreate(aQuery);
    T.ID        := aQuery.Fields[0].AsInteger;
    T.ID_Parent := aQuery.Fields[1].AsInteger;
    T.Caption   := aQuery.Fields[2].AsString;
    T.Order     := aQuery.Fields[3].AsInteger;
    T.ShowHint  := true;
    T.Hint      := T.Caption;
    L.Add(T);
    aQuery.Next;
  end;

  result:=TTreeCharts.Create;
  result.Item:=TreeItemCreate(nil);
  result.ExtractSubNodes(L);
  L.Free;
  result.Resort;
end;

function CompareTreeItems(P1,P2 : pointer) : integer;
var T1,T2 : TTreeChart;
begin
  T1:=TTreeCharts(P1).Item;
  T2:=TTreeCharts(P2).Item;
  if T1.Order > T2.Order then result :=  1 else
  if T1.Order < T2.Order then result := -1 else
  result:=CompareText(T1.Caption, T2.Caption);
end;


destructor  TTreeCharts.Destroy;
begin
  if (Item <> nil) then
  begin
    if (Item.Parent <> nil)
    then Item.Parent.RemoveControl(Item)
    else Item.Free;
  end;
  inherited;
end;

procedure   TTreeCharts.Resort;
var I : integer;
begin
  Sort(CompareTreeItems);
  for I:=0 to Count-1 do
  TTreeCharts(Items[I]).Resort;
end;

procedure   TTreeCharts.ExtractSubNodes(L : TObjectList);
var I : integer;
    T : TTreeCharts;
begin
  I:=0;
  while I < L.Count do
  if TTreeChart(L[I]).ID_Parent=Item.ID then
  begin
    T:=TTreeCharts.Create;
    Add(T);
    T.Item:=TTreeChart(L.Extract(L[I]));
    T.Item.ParentNode:=Self;
    T.Item.ParentView:=Self.Item;
    T.Parent:=Self;
  end else inc(I);
  for I:=0 to Count-1 do
    TTreeCharts(Items[I]).ExtractSubNodes(L);
end;


procedure   TTreeCharts.MaxSubLevels(fCur : integer; var fMax : integer);
var I : integer;
begin
  if fCur > fMax
     then fMax:=fCur;
  if Count > 0 then
    for I:=0 to Count-1 do TTreeCharts(Items[I]).MaxSubLevels(fCur+1,fMax);
end;

procedure   TTreeCharts.IncSubCount(var CNT : integer);
var I : integer;
begin
  if Count > 1 then inc(CNT,Count-1);
  for I:=0 to Count-1 do
    TTreeCharts(Items[I]).IncSubCount(CNT);
end;

procedure   TTreeCharts.CalcTop(aTop : integer);
var I : integer;
    T : TTreeCharts;
begin
  Item.Top:=aTop;
  for I:=0 to Count-1 do
  begin
    T:=TTreeCharts(Items[I]);
    T.CalcTop(aTop);
    aTop:=aTop+T.Item.Height;
  end;
end;

procedure   TTreeCharts.SetLeft(aMetrics : PTreeMetrics; aLeft : integer);
var I : integer;
begin
  Item.Left:=aLeft;
  Item.Width:=aMetrics.Width;
  for I:=0 to Count-1 do
    TTreeCharts(Items[I]).SetLeft(aMetrics, aLeft-aMetrics.Width);
end;

procedure   TTreeCharts.CalcLeft(aMetrics : PTreeMetrics);
var I,M : integer;
begin
  M:=0;
  MaxSubLevels(0,M);
  Item.Left:=M * aMetrics.Width;
  Item.Width:=aMetrics.Width;
  for I:=0 to Count-1 do
    TTreeCharts(Items[I]).SetLeft(aMetrics, Item.Left-aMetrics.Width);
end;

procedure   TTreeCharts.CalcHeight(aMetrics : PTreeMetrics);
var H : integer;
    I : integer;
begin
  H:=1;
  IncSubCount(H);
  Item.Height:=H*aMetrics.Height;
  for I:=0 to Count-1 do
    TTreeCharts(Items[I]).CalcHeight(aMetrics);
end;

procedure   TTreeCharts.CalcIndent(aMetrics : PTreeMetrics);
var I : integer;
begin
  Item.Width:=Item.Width-aMetrics.X_Indent* 2;
  Item.Left:=Item.Left+aMetrics.X_Indent;

  Item.Height:=Item.Height-aMetrics.Y_Indent *2;
  Item.Top:=Item.Top+aMetrics.Y_Indent;

  for I:=0 to Count-1 do
    TTreeCharts(Items[I]).CalcIndent(aMetrics);
end;

procedure   TTreeCharts.CalcMetrics(aMetrics : PTreeMetrics);
begin
  CalcLeft(aMetrics);
  CalcHeight(aMetrics);
  CalcTop(0);
  CalcIndent(aMetrics);
  LastMetrics:=aMetrics^;
end;


procedure   TTreeCharts.SetView(aView : TWinControl);
var I : integer;
begin
  Item.AutoSize:=false;
  Item.Color:=clWhite;


  aView.InsertControl(Item);
  Item.OnClick:=TPanel(aView).onClick;
  for I:=0 to Count-1 do
    TTreeCharts(Items[I]).SetView(aView);
end;

function    TTreeCharts.FindItem(aItem : TTreeChart) : TTreeCharts;
var I : integer;
    T : TTreeCharts;
begin
  result:=nil;
  if Item = aItem then result:=Self else
  for I:=0 to Count-1 do
  begin
    T:=TTreeCharts(Items[I]);
    result:=T.FindItem(aItem);
    if result<>nil then break;
  end;
end;


procedure   TTreeCharts.DeleteItem(aItem : TTreeChart);
var T : TTreeCharts;
begin
  T:=FindItem(aItem);
  if T <> nil then
  begin
    T.Parent.Remove(T);
    CalcMetrics(@LastMetrics);
  end;
end;

procedure  TTreeCharts.AddItem(aItem : TTreeChart);
var T : TTreeCharts;
begin
  T:=TTreeCharts.Create;
  Add(T);
  T.Item:=aItem;
  T.Item.Color:=Item.Color;
  T.Item.ParentNode:=Self;
  T.Item.ParentView:=Self.Item;
  T.Parent:=Self;
  Item.Parent.InsertControl(aItem);
  T.Item.OnClick:=TPanel(Item.Parent).onClick;
end;

end.

it was the base for my final solution and i said he gets 500 pts a-graded and now he gets it, if he want or not :-)

many thanks igor
(i will send the final to you soon)

meikl ;-)
0
 
LVL 10

Expert Comment

by:Lischke
ID: 2914976
Well earned Igor, see you soon in the Top15 :-) Btw: If you are interested in a totally rewritten tree control then write me and I send you my Virtual Tree (VT). Perhaps you have ideas to put some extra cool stuff into it or can provide other help. The tree will be open source, btw.

Ciao, Mike
0
 
LVL 9

Expert Comment

by:ITugay
ID: 2917958
Hi all,

meikl, thanx a lot;) realy!

Mike, OK, let's try. I have a big adventures with any sorts of tree. And loading/saving tree from/to DB is my lovelly task;)

----
igor@novell.kz
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Delphi OLE Error 8 84
Delphi cmd execution 6 42
select query - oracle 16 82
tidtcpserver connection lost handle 2 49
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now