如何通过按散点图中的更新按钮来更改(过渡)每个圆的半径?

时间:2019-10-04 01:54:54

标签: javascript d3.js scatter-plot

我是d3-v5中的新手,正在尝试使用“更新”按钮创建基本的散点图。

我使用Math.floor(Math.random() *100)创建了一个具有10个随机(0到100之间)数据的散点图,并且cxcy用一个更新按钮变化得很好。但是,axis(x,y)的过渡和半径没有正确更改。.

x和y轴均应更改为cxcy,但不能更改。

以下代码是具有更新功能的HTML脚本,

<script>
  //Scatter Plot
  //Creating data
  let data1 = [
      {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
      {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
      {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
      {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
      {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
      {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
      {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
      {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
      {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
      {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)}
  ]


  //Creating svg, margin, width, height
  let svg1 = d3.select("#svg1")
  let margin1 = 30;
  let width1 = 500 - 2 * margin1;
  let height1 = 500 - 2 * margin1;

  //Creating xScale and yScale
  let xScale1 = d3.scaleLinear()
      .range([0, width1])
      .domain([d3.min(data1, d=>d.x_val), d3.max(data1, d=>d.x_val)])
  let yScale1 = d3.scaleLinear()
      .range([height1, 0])
      .domain([d3.min(data1, d=>d.y_val), d3.max(data1, d=>d.y_val)])

  let plot1 = svg1.append('g')
      .attr('transform', 'translate(30, 30)')

  plot1.append('g')
    .attr('transform', 'translate(0, 440)')
    .call(d3.axisBottom(xScale1));
  plot1.append('g')
    .call(d3.axisLeft(yScale1));

  let colorScale1 = d3.scaleOrdinal(d3.schemeCategory10)

  plot1.selectAll()
    .data(data1)
    .enter()
    .append('circle')
    .attr('cx', (d) => xScale1(d.x_val))
    .attr('cy', (d) => yScale1(d.y_val))
    .attr('r', 5)
    .attr('height', height1)
    .attr('width', width1)

  //Putting colors on the bar
  plot1.selectAll('circle')
      .style('fill', d => colorScale1(d.x_val))
      .on('mouseenter', function(){
        d3.select(this)
          .transition()
          .duration(300)
          .attr('r', 15)
          .style('fill', 'lightblue')
      })
      .on('mouseleave', function(){
        d3.select(this)
          .transition()
          .duration(300)
          .attr('r', 5)
          .style('fill', d => colorScale1(d.x_val))
      })
  function updateData(){
    //For updating scatter plot============================================
    let data1 = [
        {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
        {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
        {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
        {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
        {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
        {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
        {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
        {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
        {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)},
        {x_val: Math.floor(Math.random() * 100), y_val: Math.floor(Math.random() * 100)}
    ]
    //Creating xScale and yScale
    let xScale1 = d3.scaleLinear()
        .range([0, width1])
        .domain([d3.min(data1, d=>d.x_val), d3.max(data1, d=>d.x_val)])
    let yScale1 = d3.scaleLinear()
        .range([height1, 0])
        .domain([d3.min(data1, d=>d.y_val), d3.max(data1, d=>d.y_val)])

    let u1 = plot1.selectAll('circle')
        .data(data1)
    u1
      .enter()
      .append('circle')
      .merge(u1)
      .transition()
      .duration(1000)
        .attr('cx', (d) => xScale1(d.x_val))
        .attr('cy', (d) => yScale1(d.y_val))
        .attr('r', Math.floor(Math.random() * 30)
        .attr('height', height1)
        .attr('width', width1)
}

这是带有我创建的更新按钮的散点图的图像

Scatter plot with an update button

我应该从代码中解决什么..?是因为selectAll吗?

请帮帮我。.

谢谢。

1 个答案:

答案 0 :(得分:1)

半径的过渡工作正常。但是,如果您希望每个圆具有不同的半径,则可以使用:

.attr('r', Math.floor(Math.random() * 30)

应该是:

.attr('r', function() {
    return Math.floor(Math.random() * 30)
})

这是您所做的更改的代码:

 let data1 = [{
     x_val: Math.floor(Math.random() * 100),
     y_val: Math.floor(Math.random() * 100)
   },
   {
     x_val: Math.floor(Math.random() * 100),
     y_val: Math.floor(Math.random() * 100)
   },
   {
     x_val: Math.floor(Math.random() * 100),
     y_val: Math.floor(Math.random() * 100)
   },
   {
     x_val: Math.floor(Math.random() * 100),
     y_val: Math.floor(Math.random() * 100)
   },
   {
     x_val: Math.floor(Math.random() * 100),
     y_val: Math.floor(Math.random() * 100)
   },
   {
     x_val: Math.floor(Math.random() * 100),
     y_val: Math.floor(Math.random() * 100)
   },
   {
     x_val: Math.floor(Math.random() * 100),
     y_val: Math.floor(Math.random() * 100)
   },
   {
     x_val: Math.floor(Math.random() * 100),
     y_val: Math.floor(Math.random() * 100)
   },
   {
     x_val: Math.floor(Math.random() * 100),
     y_val: Math.floor(Math.random() * 100)
   },
   {
     x_val: Math.floor(Math.random() * 100),
     y_val: Math.floor(Math.random() * 100)
   }
 ]


 d3.select("button").on("click", updateData)

 //Creating svg, margin, width, height
 let svg1 = d3.select("#svg1")
 let margin1 = 30;
 let width1 = 500 - 2 * margin1;
 let height1 = 500 - 2 * margin1;

 //Creating xScale and yScale
 let xScale1 = d3.scaleLinear()
   .range([0, width1])
   .domain([d3.min(data1, d => d.x_val), d3.max(data1, d => d.x_val)])
 let yScale1 = d3.scaleLinear()
   .range([height1, 0])
   .domain([d3.min(data1, d => d.y_val), d3.max(data1, d => d.y_val)])

 let plot1 = svg1.append('g')
   .attr('transform', 'translate(30, 30)')

 plot1.append('g')
   .attr('transform', 'translate(0, 440)')
   .call(d3.axisBottom(xScale1));
 plot1.append('g')
   .call(d3.axisLeft(yScale1));

 let colorScale1 = d3.scaleOrdinal(d3.schemeCategory10)

 plot1.selectAll()
   .data(data1)
   .enter()
   .append('circle')
   .attr('cx', (d) => xScale1(d.x_val))
   .attr('cy', (d) => yScale1(d.y_val))
   .attr('r', 5)
   .attr('height', height1)
   .attr('width', width1)

 //Putting colors on the bar
 plot1.selectAll('circle')
   .style('fill', d => colorScale1(d.x_val))
   .on('mouseenter', function() {
     d3.select(this)
       .transition()
       .duration(300)
       .attr('r', 15)
       .style('fill', 'lightblue')
   })
   .on('mouseleave', function() {
     d3.select(this)
       .transition()
       .duration(300)
       .attr('r', 5)
       .style('fill', d => colorScale1(d.x_val))
   })

 function updateData() {
   //For updating scatter plot============================================
   let data1 = [{
       x_val: Math.floor(Math.random() * 100),
       y_val: Math.floor(Math.random() * 100)
     },
     {
       x_val: Math.floor(Math.random() * 100),
       y_val: Math.floor(Math.random() * 100)
     },
     {
       x_val: Math.floor(Math.random() * 100),
       y_val: Math.floor(Math.random() * 100)
     },
     {
       x_val: Math.floor(Math.random() * 100),
       y_val: Math.floor(Math.random() * 100)
     },
     {
       x_val: Math.floor(Math.random() * 100),
       y_val: Math.floor(Math.random() * 100)
     },
     {
       x_val: Math.floor(Math.random() * 100),
       y_val: Math.floor(Math.random() * 100)
     },
     {
       x_val: Math.floor(Math.random() * 100),
       y_val: Math.floor(Math.random() * 100)
     },
     {
       x_val: Math.floor(Math.random() * 100),
       y_val: Math.floor(Math.random() * 100)
     },
     {
       x_val: Math.floor(Math.random() * 100),
       y_val: Math.floor(Math.random() * 100)
     },
     {
       x_val: Math.floor(Math.random() * 100),
       y_val: Math.floor(Math.random() * 100)
     }
   ]
   //Creating xScale and yScale
   let xScale1 = d3.scaleLinear()
     .range([0, width1])
     .domain([d3.min(data1, d => d.x_val), d3.max(data1, d => d.x_val)])
   let yScale1 = d3.scaleLinear()
     .range([height1, 0])
     .domain([d3.min(data1, d => d.y_val), d3.max(data1, d => d.y_val)])

   let u1 = plot1.selectAll('circle')
     .data(data1)
   u1
     .enter()
     .append('circle')
     .merge(u1)
     .transition()
     .duration(1000)
     .attr('cx', (d) => xScale1(d.x_val))
     .attr('cy', (d) => yScale1(d.y_val))
     .attr('r', function() {
       return Math.floor(Math.random() * 30)
     })
     .attr('height', height1)
     .attr('width', width1)
 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<button>Update</button>
<br>
<svg id="svg1" width="600" height="600"></svg>