Exemple #1
0
            public void Recalculate(NodeControlSceneData nodeI, NodeControlSceneData nodeJ)
            {
                box_i.X      = nodeI.Left;
                box_i.Y      = nodeI.Top;
                box_i.Width  = nodeI.Width;
                box_i.Height = nodeI.Height;
                box_j.X      = nodeJ.Left;
                box_j.Y      = nodeJ.Top;
                box_j.Width  = nodeJ.Width;
                box_j.Height = nodeJ.Height;

                box_distance   = BoxDistance.CalculateDistanceBetweenTwoBoxes(box_i, box_j);
                minimum_extent = Math.Min(Math.Min(nodeI.Width, nodeI.Height), Math.Min(nodeJ.Width, nodeJ.Height));

                delta_x = nodeI.CentreX - nodeJ.CentreX;
                delta_y = nodeI.CentreY - nodeJ.CentreY;

                distance = Math.Sqrt(delta_x * delta_x + delta_y * delta_y);
                if (1 > distance)
                {
                    distance = 1;
                }

                angle = Math.Atan2(delta_y, delta_x);

                unit_x = Math.Cos(angle);
                unit_y = Math.Sin(angle);
            }
        internal static void AddSiblingToNodeControl(NodeControl node_control)
        {
            List <ConnectorControl> connectors_both;
            List <ConnectorControl> connectors_to;
            List <ConnectorControl> connectors_from;

            GetAdjoiningConnectors(node_control.scene_rendering_control, node_control, out connectors_both, out connectors_to, out connectors_from);

            double left   = node_control.scene_data.CentreX;
            double top    = node_control.scene_data.CentreY;
            double width  = node_control.scene_data.Width;
            double height = node_control.scene_data.Height;

            top += 1.5 * height;

            NodeControlSceneData scene_data = new NodeControlSceneData();
            object      content             = new StringNodeContent("Sibling node");
            NodeControl node_new            = node_control.scene_rendering_control.AddNewNodeControl(content, left, top, width, height);

            if (connectors_to.Count > 0)
            {
                NodeControl node_control_parent = connectors_to[connectors_to.Count - 1].node_from;

                ConnectorControl connector_new = new ConnectorControl(node_control.scene_rendering_control);
                connector_new.SetNodes(node_control_parent, node_new);
                node_control.scene_rendering_control.AddNewConnectorControl(connector_new);
            }

            node_control.scene_rendering_control.SetSelectedNodeControl(node_new, false);
        }
Exemple #3
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);
        }
Exemple #4
0
            public void Recalculate(NodeControlSceneData nodeI, NodeControlSceneData nodeJ)
            {
                box_i.X      = nodeI.Left;
                box_i.Y      = nodeI.Top;
                box_i.Width  = nodeI.Width;
                box_i.Height = nodeI.Height;
                box_j.X      = nodeJ.Left;
                box_j.Y      = nodeJ.Top;
                box_j.Width  = nodeJ.Width;
                box_j.Height = nodeJ.Height;

                box_distance = BoxDistance.CalculateDistanceBetweenTwoBoxes(box_i, box_j);

#if UNUSED_CODE
                // Utilities codebase had:
                // (https://github.com/jimmejardine/qiqqa-open-source/issues/26)
                minimum_extent = Math.Min(Math.Min(nodeI.Width, nodeI.Height), Math.Min(nodeJ.Width, nodeJ.Height));
#else
                // Qiqqa codebase had:
                //
                //Logging.Debug(" DIST {0}", box_distance);
                maximum_extent = Math.Max(Math.Max(nodeI.Width, nodeI.Height), Math.Max(nodeJ.Width, nodeJ.Height));
                //minimum_extent = Math.Min(Math.Min(nodeI.Width, nodeI.Height), Math.Min(nodeJ.Width, nodeJ.Height));
#endif

                delta_x = nodeI.CentreX - nodeJ.CentreX;
                delta_y = nodeI.CentreY - nodeJ.CentreY;

                distance = Math.Sqrt(delta_x * delta_x + delta_y * delta_y);
                if (1 > distance)
                {
                    distance = 1;
                }

                angle = Math.Atan2(delta_y, delta_x);

                unit_x = Math.Cos(angle);
                unit_y = Math.Sin(angle);
            }
Exemple #5
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();
        }
Exemple #6
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();
        }