Solved

? upsidedown tree

Posted on 2000-04-20
19
226 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
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…
This is a high-level webinar that covers the history of enterprise open source database use. It addresses both the advantages companies see in using open source database technologies, as well as the fears and reservations they might have. In this…
This video Micro Tutorial shows how to password-protect PDF files with free software. Many software products can do this, such as Adobe Acrobat (but not Adobe Reader), Nuance PaperPort, and Nuance Power PDF, but they are not free products. This vide…

705 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