javascript - 如何通过按散点图中的更新按钮来更改(过渡)每个圆的半径?
问题描述
我是 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)
}
这是我创建的带有更新按钮的散点图图像
我应该从代码中修复什么..?是因为selectAll吗?
请帮帮我。。
谢谢。
解决方案
半径的过渡工作正常。但是,如果您想为每个圆使用不同的半径,而不是:
.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>
推荐阅读
- python - 如何通过python脚本使用设置环境变量作为命令行脚本的参数
- r - R如果数据框列中的返回列表需要简单字符
- javascript - 过滤以给定数字开头的数字(正则表达式)
- azure-functions - Microsoft 附加的 Azure Web App 请求标头
- r - 仅在 dplyr 过程中 glm 后不工作 step 功能
- sql - SQL:插入后缺少列
- list - 如何将可遍历的函数应用于一个值
- python - 尝试使用范围在 csv 文件中创建序列,但只获取序列中的最后一个数字
- php - 清理控制台命令帮助输出
- python - Matplot:交互式重绘 axvline?