Как изменить (перейти) радиус каждого круга, нажав кнопку обновления в точечной диаграмме? - PullRequest
1 голос
/ 04 октября 2019

Я новичок в d3-v5 и пытаюсь создать базовый график рассеяния с помощью кнопки обновления.

Я создал график рассеяния с 10 случайными (от 0 до 100) данными, используя Math.floor(Math.random() *100) и cx и cy хорошо меняются с помощью кнопки обновления. Однако переход для axis (x, y) и радиуса не изменяется должным образом.

Обе оси x и y должны быть изменены при изменении cx и cy, но это не так.

Следующий код представляет собой скрипт 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

Что я должен исправить из кода ..? это из-за чего-то выбратьВсе?

Пожалуйста, помогите мне ..

Спасибо.

1 Ответ

1 голос
/ 04 октября 2019

Переход радиусов работает правильно. Однако, если вы хотите, чтобы у каждого круга был свой радиус, вместо:

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