pChart 2.x forum
http://wiki.pchart.net/forum/

spring chart fix
http://wiki.pchart.net/forum/viewtopic.php?f=5&t=5323
Page 1 of 1

Author:  mayco [ Fri Apr 20, 2012 6:42 am ]
Post subject:  spring chart fix

I'm looking at the spring chart code because I'm trying to model a graph containing a few hundred nodes. In this process, I've noticed that 2 nodes kept sticking to the left edge.

I've found out this is because these nodes were positioned on exactly the same location. On each iteration, the distance calculated would be 0, resulting in a high force, but the angle calculated would be 0. Since the code adds 180 to this number (to reverse the direction), this results in the two nodes moving to the left at quite a high speed (since the force is high). Problem is, that they arrive on exactly the same spot, repeating the process every iteration, and tearing appart the graph.

The fix for this is quite easy:

In the function doPass(), in the Repulstion vector calculation block, after the distance calculation, we can do a check if the calculated distance is 0, when this is the case, instead of calculating the angle, just do $Angle = rand(0,360). This will make sure that the two nodes can arrive in different locations. After some iterations, the positions will be corrected.

Code:
...
            /* Repulsion vectors */
            foreach($this->Data as $Key2 => $Settings2) {
                if ( $Key != $Key2 ) {
                    $X2 = $this->Data[$Key2]["X"];
                    $Y2 = $this->Data[$Key2]["Y"];
                    $FreeZone = $this->Data[$Key2]["FreeZone"];

                    $Distance = $this->getDistance($X1,$Y1,$X2,$Y2);

                    /* Nodes too close, repulsion occurs */
                    if ( $Distance < $FreeZone ) {
                        $Force = log(pow(2,$FreeZone-$Distance));

                        if ($Distance == 0) {
                            $Angle = rand(0,360);
                        } else {
                            $Angle = $this->getAngle($X1,$Y1,$X2,$Y2) + 180;
                        }

                        if ( $Force > 1 ) {
                            $this->Data[$Key]["Vectors"][] = array("Type"=>"R","Angle"=>$Angle % 360,"Force"=>$Force);
                        }
                    }
                }
            }
...
 

Page 1 of 1 All times are UTC
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/