D3:更改滑块时圆点不会更新

时间:2017-08-23 04:22:01

标签: javascript math d3.js

我开始尝试将D3简单化为业余爱好而且我想创建一种动画类型,显示“method of exhaustion”以近似圆形区域。我希望获得的行为显示在animation

我能够绘制圆圈,圆圈周围的点以及三角形。现在我正在开发一个名为'update'的函数,它在侦听HTML上的滑块事件时会动态更改'n'的值,并使用它来重新计算坐标并在屏幕上显示它们。

我已经设法能够更改圆圈的填充但除此之外,更新功能不会更新圆圈的坐标以及添加新圆圈。我真的很感激,如果有人可以帮助我实现这一目标,并提供一些有关我的方法失败的见解。

var w = 500;
var h = 500;
var n = 17;
var r = h / 2 - 20;
var coords = [];
//var id = 0;

function points() {
  coords = []; //Clear Coords Array

  for (var i = 0; i < n; i++) {
    var p_i = {};
    p_i.x = w / 2 + r * math.cos((2 * math.pi / n) * i);
    p_i.y = h / 2 - r * math.sin((2 * math.pi / n) * i);
    p_i.id = i;
    coords.push(p_i);
  }

  //id++;
};

points(); //Generate Points

var svg = d3.select('body') //SVG Canvas
  .append('svg')
  .attr('width', w)
  .attr('height', h);

var circle = svg.append('circle') //Draw Big Circle
  .attr('cx', w / 2)
  .attr('cy', h / 2)
  .attr('r', r)
  .attr('fill', 'teal')
  .attr('stroke', 'black')
  .attr('stroke-width', w / 100);

var center = svg.append('circle') //Construct Center
  .attr('cx', w / 2)
  .attr('cy', h / 2)
  .attr('r', r / 50)
  .attr('fill', 'red')
  .attr('stroke', 'red')
  .attr('stroke-width', w / 100);

var approx_pts = svg.selectAll('circle_points') //Construct Approx Points
  .data(coords, function(d) {
    return d.id; //Sets Identifier to uniquely identify data. 
  })
  .enter()
  .append('circle')
  .attr('cx', function(d) {
    return d.x;
  })
  .attr('cy', function(d) {
    return d.y;
  })
  .attr('r', w / 100)
  .attr('fill', 'red');

var approx_tri = svg.selectAll('polygon') //Draw Triangles
  .data(coords, function(d) {
    return d.id;
  })
  .enter()
  .append('polygon')
  .attr('points', function(d, i) {
    if (i != n - 1) {
      return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[i + 1].x + ',' + coords[i + 1].y;
    } else {
      return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[0].x + ',' + coords[0].y;
    }
  })
  .attr('fill', 'Transparent')
  .attr('stroke', 'orange')
  .attr('stroke-width', w / 250);

d3.select('#slider') //Listen to Slider Event Change
  .on('input', function() {
    n = +this.value;
    update(n);
  });

function update() {
  console.log('Hey man!');
  points(); // Re-generate points
  console.log('coords[1].x = ' + coords[1].x);
  console.log('coords[1].y = ' + coords[1].y);

  //Make Selection
  approx_pts
    .selectAll('circle')
    .data(coords, function(d) {
      return d.id;
    });

  approx_pts
    .attr('fill', 'blue')
    .attr('r', r / 25);

  approx_pts
    .enter()
    .append('circle')
    .attr('cx', function(d) {
      return d.x;
    })
    .attr('cy', function(d) {
      return d.y;
    })
    .attr('r', r / 50)
    .attr('fill', 'green');
};
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.16.2/math.min.js"></script>
<input id="slider" type="range" min="3" max="100" step="1" value="3">

3 个答案:

答案 0 :(得分:3)

您错过了正确的“输入”,“更新”和“退出”选项:

var updateSelection = svg.selectAll('.circle_points')
    .data(coords, function(d) {
        return d.id;
    });

var exitSelection = updateSelection.exit().remove();

updateSelection.attr('cx', function(d) {
        return d.x;
    })
    .attr('cy', function(d) {
        return d.y;
    })
    .attr('r', r / 50)
    .attr('fill', 'blue')
    .attr('r', r / 25);

var enterSelection = updateSelection.enter()
    .append('circle')
    .attr('cx', function(d) {
        return d.x;
    })
    .attr('cy', function(d) {
        return d.y;
    })
    .attr('r', r / 50)
    .attr('fill', 'green')
    .attr("class", "circle_points");

以下是包含这些更改的代码:

var w = 500;
var h = 500;
var n = 17;
var r = h / 2 - 20;
var coords = [];
//var id = 0;

function points() {
  coords = []; //Clear Coords Array

  for (var i = 0; i < n; i++) {
    var p_i = {};
    p_i.x = w / 2 + r * math.cos((2 * math.pi / n) * i);
    p_i.y = h / 2 - r * math.sin((2 * math.pi / n) * i);
    p_i.id = i;
    coords.push(p_i);
  }

  //id++;
};

points(); //Generate Points

var svg = d3.select('body') //SVG Canvas
  .append('svg')
  .attr('width', w)
  .attr('height', h);

var circle = svg.append('circle') //Draw Big Circle
  .attr('cx', w / 2)
  .attr('cy', h / 2)
  .attr('r', r)
  .attr('fill', 'teal')
  .attr('stroke', 'black')
  .attr('stroke-width', w / 100);

var center = svg.append('circle') //Construct Center
  .attr('cx', w / 2)
  .attr('cy', h / 2)
  .attr('r', r / 50)
  .attr('fill', 'red')
  .attr('stroke', 'red')
  .attr('stroke-width', w / 100);

var approx_pts = svg.selectAll('circle_points') //Construct Approx Points
  .data(coords, function(d) {
    return d.id; //Sets Identifier to uniquely identify data. 
  })
  .enter()
  .append('circle')
  .attr('cx', function(d) {
    return d.x;
  })
  .attr('cy', function(d) {
    return d.y;
  })
  .attr('r', w / 100)
  .attr('fill', 'red')
  .attr("class", "circle_points");

var approx_tri = svg.selectAll('polygon') //Draw Triangles
  .data(coords, function(d) {
    return d.id;
  })
  .enter()
  .append('polygon')
  .attr('points', function(d, i) {
    if (i != n - 1) {
      return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[i + 1].x + ',' + coords[i + 1].y;
    } else {
      return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[0].x + ',' + coords[0].y;
    }
  })
  .attr('fill', 'Transparent')
  .attr('stroke', 'orange')
  .attr('stroke-width', w / 250);

d3.select('#slider') //Listen to Slider Event Change
  .on('input', function() {
    n = +this.value;
    update(n);
  });

function update() {
  points(); // Re-generate points

  //Make Selection
  var updateSelection = svg.selectAll('.circle_points')
    .data(coords, function(d) {
      return d.id;
    });

  var exitSelection = updateSelection.exit().remove();

  updateSelection.attr('cx', function(d) {
      return d.x;
    })
    .attr('cy', function(d) {
      return d.y;
    })
    .attr('r', r / 50)
    .attr('fill', 'blue')
    .attr('r', r / 25);

  var enterSelection = updateSelection.enter()
    .append('circle')
    .attr('cx', function(d) {
      return d.x;
    })
    .attr('cy', function(d) {
      return d.y;
    })
    .attr('r', r / 50)
    .attr('fill', 'green')
    .attr("class", "circle_points");
};
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.16.2/math.min.js"></script>
<input id="slider" type="range" min="3" max="100" step="1" value="3">

答案 1 :(得分:1)

您需要删除&#39; circle_points&#39;然后是.exit()。remove()然后是.enter()

此处需要Update Pattern

&#13;
&#13;
var w = 500;
var h = 250;
var n = 4;
var r = h / 2 - 201
var coords = [];
//var id = 0;

function points() {
  coords = []; //Clear Coords Array

  for (var i = 0; i < n; i++) {
    var p_i = {};
    p_i.x = w / 2 + r * math.cos((2 * math.pi / n) * i);
    p_i.y = h / 2 - r * math.sin((2 * math.pi / n) * i);
    p_i.id = i;
    coords.push(p_i);
  }
};

points(); //Generate Points

var svg = d3.select('body') //SVG Canvas
  .append('svg')
  .attr('width', w)
  .attr('height', h);

var circle = svg.append('circle') //Draw Big Circle
  .attr('cx', w / 2)
  .attr('cy', h / 2)
  .attr('r', r)
  .attr('fill', 'teal')
  .attr('stroke', 'black')
  .attr('stroke-width', w / 100);

var center = svg.append('circle') //Construct Center
  .attr('cx', w / 2)
  .attr('cy', h / 2)
  .attr('r', r / 50)
  .attr('fill', 'red')
  .attr('stroke', 'red')
  .attr('stroke-width', w / 100);

var approx_pts = svg.selectAll('circle_points') //Construct Approx Points
  .data(coords, function(d) {
    return d.id; //Sets Identifier to uniquely identify data.
  })
  .enter()
  .append('circle')
  .attr('cx', function(d) {
    return d.x;
  })
  .attr('cy', function(d) {
    return d.y;
  })
  .attr('r', w / 100)
  .attr('fill', 'red');

var approx_tri = svg.selectAll('polygon') //Draw Triangles
  .data(coords, function(d) {
    return d.id;
  })
  .enter()
  .append('polygon')
  .attr('points', function(d, i) {
    if (i != n - 1) {
      return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[i + 1].x + ',' + coords[i + 1].y;
    } else {
      return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[0].x + ',' + coords[0].y;
    }
  })
  .attr('fill', 'Transparent')
  .attr('stroke', 'orange')
  .attr('stroke-width', w / 250);

d3.select('#slider') //Listen to Slider Event Change
  .on('input', function() {
    n = +this.value;
    update(n);
  });

function update(n) {
  points(); // Re-generate points

  d3.selectAll("circle").remove();
  var approx_pts = svg.selectAll('circle_points') //Construct Approx Points
    .data(coords);

  approx_pts.exit().remove();

  approx_pts.enter()
    .append('circle')
    .attr('cx', function(d) {
      return d.x;
    })
    .attr('cy', function(d) {
      return d.y;
    })
    .attr('r', 6)
    .attr('fill', 'red');

  d3.selectAll("polygon").remove();
  var approx_tri = svg.selectAll('polygon') //Draw Triangles
    .data(coords)

  approx_tri.exit().remove();

  approx_tri.enter()
    .append('polygon')
    .attr('points', function(d, i) {
      if (i != n - 1) {
        return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[i + 1].x + ',' + coords[i + 1].y;
      } else {
        return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[0].x + ',' + coords[0].y;
      }
    })
    .attr('fill', 'Transparent')
    .attr('stroke', 'orange')
    .attr('stroke-width', w / 250);
};
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.16.2/math.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<!DOCTYPE html>
<meta charset="utf-8">

<body>
  <input id="slider" type="range" min="3" max="100" step="4" value="17">
</body>
&#13;
&#13;
&#13;     

答案 2 :(得分:0)

&#13;
&#13;
var w = 500;
var h = 500;
var n = 17;
var r = h / 2 - 20;
var coords = [];
//var id = 0;

function points() {
  coords = []; //Clear Coords Array

  for (var i = 0; i < n; i++) {
    var p_i = {};
    p_i.x = w / 2 + r * math.cos((2 * math.pi / n) * i);
    p_i.y = h / 2 - r * math.sin((2 * math.pi / n) * i);
    p_i.id = i;
    coords.push(p_i);
  }

  //id++;
};

points(); //Generate Points

var svg = d3.select('body') //SVG Canvas
  .append('svg')
  .attr('width', w)
  .attr('height', h);

var circle = svg.append('circle') //Draw Big Circle
  .attr('cx', w / 2)
  .attr('cy', h / 2)
  .attr('r', r)
  .attr('fill', 'teal')
  .attr('stroke', 'black')
  .attr('stroke-width', w / 100);

var center = svg.append('circle') //Construct Center
  .attr('cx', w / 2)
  .attr('cy', h / 2)
  .attr('r', r / 50)
  .attr('fill', 'red')
  .attr('stroke', 'red')
  .attr('stroke-width', w / 100);

var approx_pts = svg.selectAll('circle_points') //Construct Approx Points
  .data(coords, function(d) {
    return d.id; //Sets Identifier to uniquely identify data. 
  })
  .enter()
  .append('circle')
  .attr('cx', function(d) {
    return d.x;
  })
  .attr('cy', function(d) {
    return d.y;
  })
  .attr('r', w / 100)
  .attr('fill', 'red');

var approx_tri = svg.selectAll('polygon') //Draw Triangles
  .data(coords, function(d) {
    return d.id;
  })
  .enter()
  .append('polygon')
  .attr('points', function(d, i) {
    if (i != n - 1) {
      return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[i + 1].x + ',' + coords[i + 1].y;
    } else {
      return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[0].x + ',' + coords[0].y;
    }
  })
  .attr('fill', 'Transparent')
  .attr('stroke', 'orange')
  .attr('stroke-width', w / 250);

d3.select('#slider') //Listen to Slider Event Change
  .on('input', function() {
    n = +this.value;
    update(n);
  });

function update(n) {
  //console.log('Hey man!');
  points(); // Re-generate points
  //console.log('coords[1].x = ' + coords[1].x);
  //console.log('coords[1].y = ' + coords[1].y);

  //Make Selection
  approx_pts
    .selectAll('circle')
    .data(coords, function(d) {
      return d.id;
    });

  approx_pts
.attr('fill', 'blue')
.attr('r', r / 25);


  approx_pts
   
.attr('cx', function(d) {

  return (d.x)+n;
})
.attr('cy', function(d) {
  return d.y+n;
})
.attr('r', r / 50)
.attr('fill', 'green');
};
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.16.2/math.min.js"></script>
<input id="slider" type="range" min="3" max="100" step="1" value="3">
&#13;
&#13;
&#13;

  

请记住在拖动时更新值