2017-02-02 8 views
0

update()機能に問題があります。ここでは、svg.append('rect')の中に私は.on('click')を持っています。私は単純にデータを変更してからupdate()を実行します。D3:トラブル更新の選択

なぜこれは機能しませんか?私はそれをどのように機能させるのですか?

var width = 640, 
     height = 480; 

    var graphNodes = [ 
    { id: 0, x: 39, y: 343, r: 15 }, 
    { id: 1, x: 425, y: 38, r: 15 }, 
    { id: 2, x: 183, y: 417, r: 15 }, 
    { id: 3, x: 564, y: 31, r: 15 }, 
    { id: 4, x: 553, y: 351, r: 15 }, 
    { id: 5, x: 454, y: 298, r: 15 }, 
    { id: 6, x: 493, y: 123, r: 15 }, 
    { id: 7, x: 471, y: 427, r: 15 }, 
    { id: 8, x: 142, y: 154, r: 15 } 
    ]; 

    var svg = d3.select('body').append('svg') 
     .attr('width', width) 
     .attr('height', height); 

    svg.append('rect') 
     .attr('class', 'graph') 
     .attr('width', width) 
     .attr('height', height) 
     .attr('fill', 'lightblue') 
     .attr('opacity', 0.3) 
     .on('click', function(){ 

     graphNodes[8].id = 'hey there'; // <----- Why doesn't this happen? 

     update(); 
     }); 

    var nodeGroup = svg.selectAll('.nodes') 
     .data(graphNodes, function(d){ return d.id; }) 
     .enter().append('g') 
     .attr('class', 'node'); 

    nodeGroup.append('circle') 
     .attr('cx', function(d) { return d.x }) 
     .attr('cy', function(d) { return d.y }) 
     .attr("r", function(d){ return d.r; }) 
     .attr("fill", "gray"); 

    nodeGroup.append('text') 
     .attr("dx", function(d){ return d.x + 20; }) 
     .attr("dy", function(d){ return d.y + 5; }) 
     .text(function(d) { return d.id }); 

    function update() { 

    if(nodeGroup){ 

     // Update nodes 
     var node = nodeGroup.data(graphNodes, function(d){ return d.id; }), 
      nodeEnter = node.enter().append('g') 
       .attr('class', 'node'); 

     nodeEnter.append('circle') 
       .attr('cx', function(d) { return d.x; }) 
       .attr('cy', function(d) { return d.y; }) 
       .attr('r', function(d){ return d.r; }) 
       .attr('fill', 'gray'); 

     nodeEnter.append('text') 
      .attr("dx", function(d){ return d.x + 20; }) 
      .attr("dy", function(d){ return d.y + 5; }) 
      .text(function(d) { return d.id }); 

     nodeGroup = nodeEnter.merge(node); 
     node.exit().remove(); 
    } 
    } 

は、ここであなたは私を残したが、ここではそれが答えとしてあるメッセージにコメントとしてこれを型付きfiddle

答えて

1

です。

入力時、更新時、終了時に行うことを分ける必要があります。入力時に、決して変更されない属性を追加して設定したいだけです。更新時にテキストを追加/変更し、半径を追加/変更したいとします。出口であなたは削除します。

// bind the data 
    var node = nodeGroup.data(graphNodes, function(d){ return d.id; }), 
     // this is the enter selection 
     nodeEnter = node.enter().append('g') 
      .attr('class', 'node'); 

    // append to enter selection 
    // append and set color, we never change color 
    nodeEnter.append('circle') 
      .attr('cx', function(d) { return d.x; }) 
      .attr('cy', function(d) { return d.y; }) 
      .attr('fill', 'gray'); 

    // again entering, append text and set position 
    nodeEnter.append('text') 
     .attr("dx", function(d){ return d.x + 20; }) 
     .attr("dy", function(d){ return d.y + 5; });   

    // nodeGroup is the enter + update selection 
    nodeGroup = nodeEnter.merge(node); 

    // change the things we want to change on every update 
    nodeGroup.select("text") 
    .text(function(d) { return d.text ? d.text : d.id }); 

    nodeGroup.select("circle") 
    .attr('r', function(d){ return d.r; }) 

    // exit, just remove 
    node.exit().remove(); 

実行コード:

var width = 640, 
 
     height = 480; 
 

 
    var graphNodes = [ 
 
    { id: 0, x: 39, y: 343, r: 15 }, 
 
    { id: 1, x: 425, y: 38, r: 15 }, 
 
    { id: 2, x: 183, y: 417, r: 15 }, 
 
    { id: 3, x: 564, y: 31, r: 15 }, 
 
    { id: 4, x: 553, y: 351, r: 15 }, 
 
    { id: 5, x: 454, y: 298, r: 15 }, 
 
    { id: 6, x: 493, y: 123, r: 15 }, 
 
    { id: 7, x: 471, y: 427, r: 15 }, 
 
    { id: 8, x: 142, y: 154, r: 15 } 
 
    ]; 
 

 
    var svg = d3.select('body').append('svg') 
 
     .attr('width', width) 
 
     .attr('height', height); 
 

 
    svg.append('rect') 
 
     .attr('class', 'graph') 
 
     .attr('width', width) 
 
     .attr('height', height) 
 
     .attr('fill', 'lightblue') 
 
     .attr('opacity', 0.3) 
 
     .on('click', function(){ 
 
     /*graphNodes.push({ 
 
      x: d3.mouse(this)[0], 
 
      y: d3.mouse(this)[1], 
 
      id: graphNodes.length, 
 
      r: 15 
 
     });*/ 
 

 
     graphNodes.splice(2, 1); 
 
     
 
     graphNodes[Math.floor(Math.random() * graphNodes.length)].text = "Tomato!"; 
 
     
 
     graphNodes[Math.floor(Math.random() * graphNodes.length)].r = Math.random() * 30; 
 
     
 
     update(); 
 
     }); 
 

 
    var nodeGroup = svg.selectAll('.nodes') 
 
     .data(graphNodes, function(d){ return d.id; }) 
 
     .enter().append('g') 
 
     .attr('class', 'node'); 
 

 
    nodeGroup.append('circle') 
 
     .attr('cx', function(d) { return d.x }) 
 
     .attr('cy', function(d) { return d.y }) 
 
     .attr("r", function(d){ return d.r; }) 
 
     .attr("fill", "gray"); 
 

 
    nodeGroup.append('text') 
 
     .attr("dx", function(d){ return d.x + 20; }) 
 
     .attr("dy", function(d){ return d.y + 5; }) 
 
     .text(function(d) { return d.id }); 
 

 
    function update() { 
 
    
 
    if(nodeGroup){ 
 

 
     // Update nodes 
 
     var node = nodeGroup.data(graphNodes, function(d){ return d.id; }), 
 
      nodeEnter = node.enter().append('g') 
 
       .attr('class', 'node'); 
 
     
 
     // this is the enter selection 
 
     // append and set color, we never change color 
 
     nodeEnter.append('circle') 
 
       .attr('cx', function(d) { return d.x; }) 
 
       .attr('cy', function(d) { return d.y; }) 
 
       .attr('fill', 'gray'); 
 

 
     nodeEnter.append('text') 
 
      .attr("dx", function(d){ return d.x + 20; }) 
 
      .attr("dy", function(d){ return d.y + 5; });   
 

 
     // nodeGroup is the enter + update selection 
 
     nodeGroup = nodeEnter.merge(node); 
 
     
 
     // change the things we want to change on every update 
 
     nodeGroup.select("text") 
 
     \t .text(function(d) { return d.text ? d.text : d.id }); 
 
     
 
     \t nodeGroup.select("circle") 
 
     \t \t .attr('r', function(d){ return d.r; }) 
 
     
 
     // exit, just remove 
 
     node.exit().remove(); 
 
    } 
 
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>

ここで私は適切に入力して、更新、終了パラダイムを扱ってきました