【问题标题】:How to change (transition) radius of each circle by pressing an update button in scatter plot?如何通过按散点图中的更新按钮来更改(过渡)每个圆的半径?
【发布时间】:2019-10-04 01:54:54
【问题描述】:

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

我使用Math.floor(Math.random() *100)cxcy 创建了一个包含 10 个随机数据(介于 0 到 100 之间)的散点图,使用更新按钮可以很好地更改。但是,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)
}

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

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

请帮帮我..

谢谢。

【问题讨论】:

    标签: javascript d3.js scatter-plot


    【解决方案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>

    【讨论】:

    • 感谢您帮助我!! :) 您建议的答案有效!我真的很感激!!我还有一个快速的问题。从我上面的代码中,我想让 x 和 y 的比例在我按下更新按钮时也应该自动更改,但它没有......应该添加什么样的代码? :'(
    • 您的体重秤已经发生变化。如果您在谈论轴,请查看此答案中的第二个 sn-p:stackoverflow.com/a/13254403/5768908
    • 哦,我的意思是 x 轴和 y 轴...抱歉混淆了。我通过参考你的链接想通了! :D 非常感谢,希望你有一个好的! :D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-29
    • 2016-12-23
    • 2019-12-03
    • 1970-01-01
    • 2012-08-18
    • 1970-01-01
    相关资源
    最近更新 更多