D3 Force Layout: добавление и удаление узлов по клику

Кажется, я не могу найти другие примеры, которые имеют схожее применение с тем, что я пытаюсь сделать, поэтому я решил просто спросить.

Я пытаюсь создать забавный инструмент для создания карт ума, используя потрясающую библиотеку d3.js от Майка Бостока. Я все еще пытаюсь выучить d3 и, как оказалось, базовое кодирование! То, что я хочу, это пустой холст и 3 кнопки; "добавить", "удалить" и "редактировать". Очень простой, я надеюсь!

  1. Когда вы выбираете кнопку "Добавить" (верхнее изображение), а затем нажимаете на пустой холст, будет добавлен узел. Если вы снова нажмете рядом, будет добавлен еще один узел, который будет связан с первым узлом.

  2. Выбрав кнопку "удалить" (среднее изображение), затем нажав на узел, вы удалите этот узел и все соприкасающиеся ссылки.

  3. Выбор кнопки "Изменить" (нижнее изображение) позволит вам пометить узлы.

У меня есть шаг 1 и половина шага 2. Проблема, с которой я сталкиваюсь, выглядит так:

  1. Нажмите кнопку "Добавить" один раз, функция добавления включена. Работает
  2. Добавьте несколько узлов. Работает
  3. Снова нажмите кнопку "Добавить", функция добавления отключена. Работает
  4. Нажмите на холст, узлы не добавляются, но существующие узлы можно перетаскивать. Работает
  5. Нажмите кнопку "Удалить" один раз, функция удаления включена "вкл". Работает
  6. Нажмите на узел, чтобы удалить его. Сломан Удаляет все.
  7. Нажмите кнопку "Удалить" еще раз, функция удаления отключена. Сломанный
  8. Снова нажмите кнопку "Добавить", функция добавления включена. Сломанный

Кто-нибудь есть какие-либо предложения относительно того, почему у меня возникла эта проблема и как они будут решать эту проблему? Я думаю, что это как-то связано с путаницей между выбором штата. При отключении функции "удалить" он вызывает ту же функцию, что и при отключении функции "добавить", поэтому он не знает, что делать, и ничего не делает... Я думал, что они не должны выбираться взаимно, но одно состояние остается включенным после включения? Я действительно в тупик:(

Я надеюсь, что могут быть части этого, которые полезны и другим людям. Спасибо! Себ

.js ниже..>>>>

//==D3 STUFFS ======================================================

//height & width of the interactive area
var divh = document.getElementById('container').offsetHeight;
var divw = document.getElementById('container').offsetWidth;

//node size
var radius = 20;

//define the nodes and links as empty data sets
var nodes = [];
var links = [];

//place the interactive area onto the browser UI with the dimensions defined above
var interactiveArea = d3.select("#container").append("svg:svg").attr("width", divw).attr("height", divh);

//enable dragging of node elements
var drag = d3.behavior.drag()
    .origin(Object)
    .on("drag", dragmove);

//define the physics parameters that will take effect on the nodes and links
var force = d3.layout.force()
    .gravity(0.01)
    .charge(-80)
    .linkDistance(60)
.nodes(nodes)
.links(links)
.size([divw, divh]);

//apply the physics parameters defined above on the nodes and links

force.on("tick", function() 
    {
    interactiveArea.selectAll("line.link")
  .attr("x1", function(d) { return d.source.x; })
  .attr("y1", function(d) { return d.source.y; })
  .attr("x2", function(d) { return d.target.x; })
  .attr("y2", function(d) { return d.target.y; });

    interactiveArea.selectAll("circle.node")
  .attr("cx", function(d) { return d.x; })
  .attr("cy", function(d) { return d.y; }); 
    });

//update the position of the object on drag

function dragmove(d) 
    {
d3.select(this)
  .attr("cx", d.x = Math.max(radius, Math.min(divw - radius, d3.event.x)))
  .attr("cy", d.y = Math.max(radius, Math.min(divh - radius, d3.event.y)));
    }

//update the force layout

function update() 
    {
interactiveArea.selectAll("line.link")
  .data(links)
  .enter().insert("svg:line", "circle.node")
  .attr("class", "link")
  .attr("x1", function(d) { return d.source.x; })
  .attr("y1", function(d) { return d.source.y; })
  .attr("x2", function(d) { return d.target.x; })
  .attr("y2", function(d) { return d.target.y; });

interactiveArea.selectAll("circle.node")
  .data(nodes)
  .enter().insert("svg:circle", "circle.cursor")
  .attr("class", "node")
  .attr("cx", function(d) { return d.x; })
  .attr("cy", function(d) { return d.y; })
  .attr("r", 10)
  .call(force.drag);

force.start();
    }

//==============================================================


//==BUTTON & EVENT SELECTOR=======================================

var addCounter = 0;
var removeCounter = 0;
var editCounter = 0;

function addButton_Off()
    {
    //alert("ADD - off");
    document.images["add-button"].src = "love.lost.PNG";
    all_Off();
    return true;
    }

function removeButton_Off()
    {
    //alert("REMOVE - off");
    document.images["remove-button"].src = "love.lost.PNG";
    //all_Off();
    return true;
    }

function editButton_Off()
    {
    //alert("EDIT - off");
    document.images["edit-button"].src = "love.lost.PNG";

    return true;
    }

function addButton()
    {
    addCounter++;
    if (addCounter%2 == 0)
        addButton_Off();
    else
        addButton_On();
        if (removeCounter%2 == 1)
            removeCounter++;
            removeButton_Off();
        if (editCounter%2 == 1)
            editCounter++;
            editButton_Off();

    function addButton_On()
        {
        //alert("ADD - on");
        document.images["add-button"].src = "pop.cloud.PNG";
        add_Nodes();
        return true;
        }
    }

function removeButton()
    {
    removeCounter++;
    if (removeCounter%2 == 0)
        removeButton_Off();
    else
        removeButton_On();
        if (addCounter%2 == 1)
            addCounter++;
            addButton_Off();
        if (editCounter%2 == 1)
            editCounter++;
            editButton_Off();

    function removeButton_On()
        {
        //alert("REMOVE - on");
        document.images["remove-button"].src = "pop.cloud.PNG";
        remove_Nodes();
        return true;
        }
    }

function editButton()

    {
    editCounter++;
    if (editCounter%2 == 0)
        editButton_Off();
    else
        editButton_On();
        if (addCounter%2 == 1)
            addCounter++;
            addButton_Off();
        if (removeCounter%2 == 1)
            removeCounter++;
            removeButton_Off();

    function editButton_On()
        {
        //alert("EDIT - on");
        document.images["edit-button"].src = "pop.cloud.PNG";
        return true;
        }
    }

//=============================================================

//==EVENT ACTIONS========================================================

function all_Off()
    {
    interactiveArea.on("mousedown", function() 
        {
        update();
        });
    }


function add_Nodes()
    {
    //do the following actions when the mouse is clicked on the interactiveArea
    interactiveArea.on("mousedown", function() 
            {
            // add a node under the mouse cursor
            var point = d3.svg.mouse(this),
                node = {x: point[0], y: point[1]},
                n = nodes.push(node);

            nodes.forEach(function(target) 
                {
                var x = target.x - node.x,
                    y = target.y - node.y;
                //if there is a node less than 30 pixels? away, add a link between the 2 nodes
                if (Math.sqrt(x * x + y * y) < 30)
                    {
                    // add links to any nearby nodes
                    links.push({source: node, target: target});
                    }
                });
            update();
            });
    }

function remove_Nodes()
    {
    interactiveArea.on("click", function()
        {
        var point = d3.select(this);
        point.remove();
        update();
        });
    }


//function edit_Nodes()

//==========================================================

HTML ниже...>>>>

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
        <link type="text/css" rel="stylesheet" href="style.css">
        <script src="http://code.jquery.com/jquery-latest.js"></script>
    </head>

    <body>
        <div id="enclosure">
            <div id="title">
            /
            </div>
            <div id="button-menu">

                <a onMouseDown="return addButton()">
                    <img name="add-button" id="add-button-img" src="love.lost.PNG" width="80px" height="80px" border = "0" alt="fuchs">
                </a>
                <a onMouseDown="return removeButton()">
                    <img name="remove-button" id="remove-button-img" src="love.lost.PNG" width="80px" height="80px" border = "0" alt="fuchs">
                </a>
                <a onMouseDown="return editButton()">
                    <img name="edit-button" id="edit-button-img" src="love.lost.PNG" width="80px" height="80px" border = "0" alt="fuchs">
                </a>

            </div>
            <div id="container">
                <script type="text/javascript" src="http://mbostock.github.com/d3/talk/20111116/d3/d3.js"></script>
                <script type="text/javascript" src="http://mbostock.github.com/d3/talk/20111116/d3/d3.geom.js"></script>
                <script type="text/javascript" src="http://mbostock.github.com/d3/talk/20111116/d3/d3.layout.js"></script>
                <script type="text/javascript" src="bonquiqui.js"></script>
                <!--<script type="text/javascript" src="origin.js"></script>-->

            </div>
        </div>
    </body>
</html>

css ниже..>>>>

body {
  font: 300 36px "Lane - Posh";
  height: 100%;
  width: 100%;
  margin: auto;
  overflow: hidden;
  position: absolute;
  text-align: center;
  background: #fff;
}

#enclosure {
  margin-top: 3%;
 }

#title {
background: #fff;
font: 300 220% "Lane - Posh";
height: 100px;
width: 60%;
margin-left: auto;
margin-right: auto;
}

#button-menu {
background: #eee;
height: 20%;
width: 4%;
position: absolute;
top: 48.0%;
left: 81%;
} 

#add-button {
cursor: pointer;
position: relative;
top: 5%;
}

#remove-button {
cursor: pointer;
position: relative;
top: 5%;
}

#edit-button {
cursor: pointer;
position: relative;
top: 5%;
}

#container {
  height: 60%;
  width: 60%;
  margin: auto;
  margin-top: 1%;
  background: #eee;
  overflow: hidden;
}   

circle.node 
  {
  cursor: pointer;
  stroke: #000;
  stroke-width: .5px;
  }

line.link 
  {
  fill: none;
  stroke: #9ecae1;
  stroke-width: 1.5px;
  }

0 ответов

Другие вопросы по тегам