D3:更改滑块时圆点不会更新 [英] D3: Circle Points don't update when changing slider

查看:68
本文介绍了D3:更改滑块时圆点不会更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始尝试学习D3只是一个爱好,我想创建一种显示'耗尽方法'来近似圆的面积。我希望获得的行为显示在动画



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



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



  var w = 500; var h = 500; var n = 17; var r = h / 2  -  20; var coords = []; // var id = 0;功能点(){coords = []; //清除Coords数组(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(); //生成Pointsvar svg = d3.select('body')// SVG Canvas .append('svg')。attr('width',w).attr('height',h); var circle = svg.append ('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')//构造中心.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')//构造近似点.data(coords,function(d){return d.id; //设置标识符以唯一标识数据。})。enter()。append('circle')。attr('cx',function(d){return dx;})。attr('cy',function(d){return dy;})。attr ('r',w / 100).attr('fill','red'); var approx_tri = svg.selectAll('polygon')// Draw Triang les .data(coords,function(d){return d.id;})。enter()。append('polygon')。attr('points',function(d,i){if(i!= n  - 1){return w / 2 +','+ h / 2 +''+ dx +','+ dy +''+ coords [i + 1] .x +','+ coords [i + 1]。 Ÿ; } 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')//听Slider Event Change .on('input',function(){n = + this.value; update(n);}); function update(){console.log('嘿man!');点(); //重新生成点console.log('coords [1] .x ='+ coords [1] .x); console.log('coords [1] .y ='+ coords [1] .y); //使选择about_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 dx;})。attr('cy',function(d){return dy;})。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 =slidertype =rangemin =3max =100 step =1value =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 dx;
})
.attr('cy',function(d){
返回dy;
})
.attr('r',r / 50)
.attr('fill','blue')
.attr( 'r',r / 25);

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

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




I've started trying to learn D3 as merely a hobby and I've wanted to create a type of animation that displays the 'method of exhaustion' to approximate the area of a circle. The behavior I wish to obtain is shown in this animation.

I have been able to draw the circle, the points around the circle as well as the triangles. Now I am working on a function called 'update' which upon listening to a slider event on the HTML dynamically changes the value for 'n' and use that to recalculate the coordinates and display them on screen.

I have managed to be able to change the fill of the circles but aside from that the update function doesn't update the coordinates of the circles as well as add new circles. I would really appreciate if someone could help me get this working as well as provide some insight as to why my approach is failing.

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">

解决方案

You are missing a proper "enter", "update" and "exit" selections:

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");

Here is your code with those changes:

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">

这篇关于D3:更改滑块时圆点不会更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆