我有一个包含圆圈和一些文字的气泡车。在检查图表时,我得到这样的结果:
。
问题是我应用的动画仅适用于圆圈。我想以某种方式将圆圈和文本组合在一起,然后在每个组上应用动画。 就像我指定的那样,有2个事件:mouseover和mouseout。我想将它们应用于圆圈和圆圈内的文本。
我的脚本如下:
var margin = 40,
width = 600,
height = 400;
var data = [{"admit_probability":54,"rank":20, "c":12},
{"admit_probability":79,"rank":111, "c":9},
{"admit_probability":70,"rank":68, "c":6},
{"admit_probability":12,"rank":1, "c":20},
{"admit_probability":197,"rank":87, "c":10}];
var xscale = d3.scaleLinear()
.domain(
d3.extent(data, function(d) { return +d.admit_probability; })
)
.nice()
.range([0, width]);
var yscale = d3.scaleLinear()
.domain(d3.extent(data, function(d) { return +d.rank; }))
.nice()
.range([height, 0]);
var xAxis = d3.axisBottom().scale(xscale);
var yAxis = d3.axisLeft().scale(yscale);
var svg = d3.select('.chart')
.append('svg')
.attr('class', 'chart')
.attr("width", width + margin + margin)
.attr("height", height + margin + margin)
.append("g")
.attr("transform", "translate(" + margin + "," + margin + ")");
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
var color = d3.scaleOrdinal(d3.schemeCategory10);
svg.selectAll("circle")
.data(data)
.enter()
.insert("circle")
.attr("cx", width / 2)
.attr("cy", height / 2)
.attr("opacity", 0.3)
.attr("r", 20)
.style("fill", "blue")
.on('mouseover', function (d, i) {
d3.select(this)
.attr("r", 32)
.style("fill", "orange");
})
.on('mouseout', function (d, i) {
fadeOut();
})
.attr("cx", function (d) { return xscale(+d.admit_probability); })
.attr("cy", function (d) { return yscale(+d.rank); });
// .ease("elastic");
var text = svg.selectAll(null)
.data(data)
.enter()
.append('text');
var textLabels = text
.attr("x", function (d) { return xscale(+d.admit_probability); })
.attr("text-anchor", "middle")
.attr("y", function (d) { return yscale(+d.rank); })
.text("Hi")
.attr("font-family", "sans-serif")
.attr("font-size", "10px")
.attr("fill", "red");
svg.append("text")
.attr("transform", "translate(" + (width / 2) + " ," + (height + margin) + ")")
.style("text-anchor", "middle")
.text("Average Acceptance");
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin)
.attr("x",0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Rank");
function fadeOut() {
svg.selectAll("circle")
.transition()
.style("opacity", 0.3)
.attr("r", 20)
.style("fill", "blue");
}
我该怎么做?
答案 0 :(得分:1)
解决方案1:
一个简单的解决方案是附加<g>
元素来保存文本和圈子:
var group = svg.selectAll(null)
.data(data)
.enter()
.append("g");
group.append("circle")
//etc...
group.append("text")
//etc...
然后将事件监听器添加到组中,同时选择文本和圈子:
group.on('mouseover', function(d, i) {
d3.select(this).select("circle")
//etc...
d3.select(this).select("text")
/etc...
})
以下是这些变化的小提琴:https://jsfiddle.net/p5f0eey1/
解决方案2:
第二种解决方案不涉及任何群体。这就是问题所在:当你想将相同的转换或相同的属性应用于一组元素时,人们会立即想到“我将它们放在一个组元素中”。问题是创建越来越多的SVG元素会降低页面速度。另一方面,这些天脚本可以非常快地运行。因此,您可以依靠脚本来选择所需的文本,只将事件监听器添加到圆圈中。
由于圆圈和文本都具有相同的数据,因此您可以在圆圈的事件处理程序中获取正确的文本:
circles.on('mouseover', function(d, i) {
d3.select(this)
.attr("r", 32)
.style("fill", "orange");
texts.filter(function(e) {
return e.rank === d.rank;
}).attr("font-size", "20px")
})
这是更新的小提琴:https://jsfiddle.net/mtjoxp3a/