diff options
Diffstat (limited to 'lib/appmon/src/appmon_place.erl')
-rw-r--r-- | lib/appmon/src/appmon_place.erl | 192 |
1 files changed, 0 insertions, 192 deletions
diff --git a/lib/appmon/src/appmon_place.erl b/lib/appmon/src/appmon_place.erl deleted file mode 100644 index fe1e909d7c..0000000000 --- a/lib/appmon/src/appmon_place.erl +++ /dev/null @@ -1,192 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2010. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%%------------------------------------------------------------ -%% -%% Places a Digraph in a tree-like manner. The vertices in the digraph -%% is updated with x and y positions. The operation is not atomic. The -%% digraph may be cyclic but edges must then have been labeled primary -%% or secondary and the set of primary links must make up a non-cyclic -%% graph (a tree). -%% -%% -%% IMPLEMENTATION DETAIL -%% --------------------- -%% -%% The placement algorithm is straightforward, place the -%% nodes in the vertical plane (y-plane) and then place -%% nodes in the horisontal plane (x-plane). -%% -%% First all nodes are placed in the y (vertical) plane -%% by a standard traversing of the tree. We then place -%% the tree in the x (horisontal) plane. Each node is -%% placed in the middle of its children as far to the -%% left as possible, preferably at the left margin. Two -%% things can make a node not be placed at the left -%% margin and that is the case when a previous node has -%% been placed at the same vertical level as the node we -%% are trying to place (thus forcing a placement further -%% to the right), and the second case is when the middle -%% of the subtree of the node is not at the left margin -%% (which it only is when the subtree is empty). The -%% algorithm obviously depends on keeping track of the -%% rightmost positions at all depths, and this -%% information is also usefull when calculating the width -%% of the tree. -%% -%% -%% -%%------------------------------------------------------------ - - - --module(appmon_place). - --export([place/2]). - --include("appmon_dg.hrl"). - - --import(lists, [foreach/2, foldl/3]). - - -place(DG, Root) -> - case appmon_dg:get(data, DG, Root) of - false -> [0]; - _Other -> - placey(DG, Root, 1), - placex(DG, Root, []) - end. - - -%%------------------------------------------------------------ -%% -%% -%% Placing a graph in y plane -%% -------------------------- -%% -%% Place nodes in the graph in the y plane rather stupidly -%% - -placey(DG, V, Y) -> - appmon_dg:set(y, DG, V, Y), - Y1 = Y+1, - foreach(fun(C) -> placey(DG, C, Y1) end, appmon_dg:get(out, DG, V)). - - - - -%%------------------------------------------------------------ -%% -%% -%% Place a tree in the x plane -%% --------------------------- -%% -%% Place nodes in the tree in the x plane. The goal of the x -%% placement is to place all nodes as far to the left as possible -%% while maintaining a nice tree shape. -%% -%% To place a node we must first place its children, the -%% intention is to place the current node in the middle and above -%% its children. The calc_mid function will place the node in the -%% middle of its children. If the node should be placed further -%% to the right than the middle of its children, then its -%% children are moved DeltaX positions to be balanced under the -%% node. Thus at the end the node and its children form a nice -%% looking tree. -%% -%% The function also maintains the 'rightmost x on each level' -%% list LastX by putting its own position on top of the list -%% -%% - -placex(DG, V, LastX) -> - Ch = appmon_dg:get(out, DG, V), - ChLX = foldl(fun(C, Accu) -> placex(DG, C, Accu) end, - tll(LastX), - Ch), - - Width = appmon_dg:get(w, DG, V), - MyX = calc_mid(DG, Width, Ch), - DeltaX = calc_delta(MyX, hdd(LastX)+spacex()), - - appmon_dg:set(x, DG, V, MyX), - move(DG, V, [MyX+Width | ChLX], DeltaX). - - -%%------------------------------------------------------------ -%% -%% -%% Move a subtree DeltaX positions to the right -%% -------------------------------------------- -%% -%% Used when moving children to balance under an already placed -%% parent. Note that the correct LastX depends on the ordering of -%% the children which must be the same as when the children were -%% first placed. It must be ensured that hdd(NewLastX) is the -%% same as hdd(NewLastX)+DeltaX. If the order of children is -%% preserved then so is hdd(LastX). Another solution would be to -%% set hdd(LastX) from the parent -%% -%% Note the two base clauses, one for the no-children case and -%% one optimisation clause (unneccessary perhaps) for DeltaX==0 -%% - -move(_DG, _L, LastX, 0) -> LastX; -move(DG, V, LastX, DeltaX) -> move2(DG, V, LastX, DeltaX). - -move2(DG, V, LastX, DeltaX) -> - NewX = appmon_dg:get(x, DG, V)+DeltaX, - appmon_dg:set(x, DG, V, NewX), - ChLX = foldl(fun(C, LX) -> move2(DG, C, LX, DeltaX) end, - tll(LastX), - appmon_dg:get(out, DG, V)), - [erlang:max(NewX+appmon_dg:get(w, DG, V), hdd(LastX)) | ChLX]. - - -%%------------------------------------------------------------ -%% -%% -%% Calculate the middle position of the children -%% --------------------------------------------- -%% -%% Calculates the mid x position for a list of children. This -%% position is later compared to the position dictated by LastX -%% in calc_delta. - -calc_mid(_DG, _Width, []) -> 0; -calc_mid(DG, Width, ChList) -> - LeftMostX = appmon_dg:get(x, DG, hd(ChList)), - Z2 = lists:last(ChList), - RightMostX = appmon_dg:get(x, DG, Z2)+appmon_dg:get(w, DG, Z2), - trunc((LeftMostX+RightMostX)/2)-trunc(Width/2). - -calc_delta(Mid, Right) -> - if Right>Mid -> Right-Mid; - true -> 0 - end. - - - -%% Special head and tail -%% Handles empty list in a non-standard way -tll([]) -> []; -tll([_|T]) -> T. -hdd([]) -> 0; -hdd([H|_]) -> H. - -spacex() -> 20. % Should be macro?? |