Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 236
  • Last Modified:

? upsidedown tree

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
kretzschmar
Asked:
kretzschmar
  • 11
  • 6
  • 2
1 Solution
 
ITugayCommented:
Hi meikl,
Is it must visualize DB table?
-----
Igor
0
 
kretzschmarAuthor Commented:
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
 
ITugayCommented:
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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
kretzschmarAuthor Commented:
yup,
would be nice.

send the shot to
meikl@spektracom.de

meikl
0
 
ITugayCommented:
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
 
kretzschmarAuthor Commented:
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
 
kretzschmarAuthor Commented:
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
 
kretzschmarAuthor Commented:
Adjusted points from 50 to 200
0
 
kretzschmarAuthor Commented:
raising points now,

found one comercial,
which may fit,

expressflowchart at
www.devexpress.com

but also overdressed

any other suggestions ?
0
 
ITugayCommented:
Meikl,
If you will increase points so fast, I will write it for you especcialy;)))
0
 
kretzschmarAuthor Commented:
:-))

well, if you can give such a solution,
which will match my needs,
then i will offer 500 Pts. A graded
0
 
LischkeCommented:
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
 
ITugayCommented:
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
 
kretzschmarAuthor Commented:
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
 
kretzschmarAuthor Commented:
Adjusted points from 200 to 500
0
 
kretzschmarAuthor Commented:
Comment accepted as answer
0
 
kretzschmarAuthor Commented:
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
 
LischkeCommented:
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
 
ITugayCommented:
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

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

  • 11
  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now