我是d3-v5中的新手,正在尝试使用“更新”按钮创建基本的散点图。
我使用Math.floor(Math.random() *100)
创建了一个具有10个随机(0到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吗?
请帮帮我。.
谢谢。
答案 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>