Example #1
0
        private void DoPushPull(NodeControlSceneData nodeI, NodeControlSceneData nodeJ, NodesVector vector, double strength)
        {
            nodeI.SetDeltaCentreX(+strength * vector.unit_x);
            nodeJ.SetDeltaCentreX(-strength * vector.unit_x);

            nodeI.SetDeltaCentreY(+strength * vector.unit_y);
            nodeJ.SetDeltaCentreY(-strength * vector.unit_y);
        }
Example #2
0
        private void DoLayout()
        {
            int SPEED = 1;

            // If the nodes and connectors have changed, recache them!
            if (cache_scene_changed_timestamp != this.scene_rendering_control.SceneChangedTimestamp)
            {
                Logging.Info("Scene has changed, so autolayout is recaching.");
                cache_scene_changed_timestamp = this.scene_rendering_control.SceneChangedTimestamp;
                cache_node_controls           = new List <NodeControl>(this.scene_rendering_control.NodeControls);
                cache_connector_controls      = new List <ConnectorControl>(this.scene_rendering_control.ConnectorControlManager.ConnectorControls);
            }

            // We reuse this so that it is memory allocation time efficient
            NodesVector vector = new NodesVector();

            // Perform the attraction
            if (true)
            {
                int MAX_CONNECTORS = cache_connector_controls.Count;
                for (int i = 0; i < MAX_CONNECTORS; ++i)
                {
                    ConnectorControl connector = cache_connector_controls[i];
                    if (connector.Deleted)
                    {
                        continue;
                    }

                    NodeControlSceneData nodeI = connector.NodeFrom.NodeControlSceneData;
                    NodeControlSceneData nodeJ = connector.NodeTo.NodeControlSceneData;

                    vector.Recalculate(nodeI, nodeJ);

                    double strength = -1 * SPEED * (vector.distance / vector.minimum_extent);
                    DoPushPull(nodeI, nodeJ, vector, strength);
                }
            }

            // Perform the repulsion
            if (true)
            {
                int MAX_NODES = cache_node_controls.Count;
                for (int i = 0; i < MAX_NODES; ++i)
                {
                    NodeControlSceneData nodeI = cache_node_controls[i].NodeControlSceneData;
                    if (nodeI.Deleted)
                    {
                        continue;
                    }

                    for (int j = i + 1; j < MAX_NODES; ++j)
                    {
                        NodeControlSceneData nodeJ = cache_node_controls[j].NodeControlSceneData;
                        if (nodeJ.Deleted)
                        {
                            continue;
                        }

                        vector.Recalculate(nodeI, nodeJ);

                        double strength = SPEED * Math.Min(2, (vector.minimum_extent / (vector.box_distance + 1)));
                        DoPushPull(nodeI, nodeJ, vector, strength);
                    }
                }
            }

            NotifySceneRenderingControl();
        }
Example #3
0
        private void DoLayout()
        {
            int SPEED = 1;

            // If the nodes and connectors have changed, recache them!
            if (cache_scene_changed_timestamp != scene_rendering_control.SceneChangedTimestamp)
            {
                Logging.Info("Scene has changed, so autolayout is recaching.");
                cache_scene_changed_timestamp = scene_rendering_control.SceneChangedTimestamp;
                cache_node_controls           = new List <NodeControl>(scene_rendering_control.NodeControls);
                cache_connector_controls      = new List <ConnectorControl>(scene_rendering_control.ConnectorControlManager.ConnectorControls);
            }

            // We reuse this so that it is memory allocation time efficient
            NodesVector vector = new NodesVector();

            // Also note that Utilities codebase had ATTRACTION *before* REPULSION.
            // Haven't looked at the precise code, but wouldn't be surprised if this is
            // very similar to the D3 force anneal code (D3.js) anyway. There aren't that
            // many ways to stabilize a (large) graph in 2D.
            //
            // See also https://github.com/jimmejardine/qiqqa-open-source/issues/26

            // Perform the repulsion
            if (true)
            {
                int MAX_NODES = cache_node_controls.Count;
                for (int i = 0; i < MAX_NODES; ++i)
                {
                    NodeControlSceneData nodeI = cache_node_controls[i].NodeControlSceneData;
                    if (nodeI.Deleted)
                    {
                        continue;
                    }

                    for (int j = i + 1; j < MAX_NODES; ++j)
                    {
                        NodeControlSceneData nodeJ = cache_node_controls[j].NodeControlSceneData;
                        if (nodeJ.Deleted)
                        {
                            continue;
                        }

                        vector.Recalculate(nodeI, nodeJ);

                        // Utilities code had:
                        //
                        // See also https://github.com/jimmejardine/qiqqa-open-source/issues/26
#if UNUSED_CODE
                        double strength = SPEED * Math.Min(2, (vector.minimum_extent / (vector.box_distance + 1)));
                        DoPushPull(nodeI, nodeJ, vector, strength);
#else
                        // Qiqqa code chunk alt:
                        double strength = vector.maximum_extent * SPEED * (1 / (vector.box_distance + 1));
                        strength = Math.Min(strength, 5);
                        if (strength > 10)
                        {
                        }
                        // end of Qiqqa alt chunk; looks to me like someone has been fiddling around here...
                        // (including the logline below, which was also not in Utilities codebase...
                        DoPushPull(nodeI, nodeJ, vector, strength);
                        //Logging.Info("REPULSE STRENGTH={0}, box.distance={1}", strength, vector.box_distance);
#endif
                    }
                }
            }

            // Perform the attraction
            if (true)
            {
                int MAX_CONNECTORS = cache_connector_controls.Count;
                for (int i = 0; i < MAX_CONNECTORS; ++i)
                {
                    ConnectorControl connector = cache_connector_controls[i];
                    if (connector.Deleted)
                    {
                        continue;
                    }

                    NodeControlSceneData nodeI = connector.NodeFrom.NodeControlSceneData;
                    NodeControlSceneData nodeJ = connector.NodeTo.NodeControlSceneData;

                    vector.Recalculate(nodeI, nodeJ);

#if UNUSED_CODE
                    // Utilities codebase was:
                    // See also https://github.com/jimmejardine/qiqqa-open-source/issues/26
                    double strength = -1 * SPEED * (vector.distance / vector.minimum_extent);
                    DoPushPull(nodeI, nodeJ, vector, strength);
#else
                    double strength = -1 * SPEED * (vector.box_distance / 50);
                    DoPushPull(nodeI, nodeJ, vector, strength);
                    //Logging.Info("ATTRACT STRENGTH={0}", strength);
#endif
                }
            }

            NotifySceneRenderingControl();
        }