是否可以通过单击 <g> 来选择 <path>?
Posted
技术标签:
【中文标题】是否可以通过单击 <g> 来选择 <path>?【英文标题】:Is it possible to select a <path> based on a click on <g>? 【发布时间】:2018-06-24 19:42:05 【问题描述】:我想做的是
-
我想单击图例(矩形和文本上的任意位置)以显示/隐藏该数据段。我可以单独在 rect 上或单独在 text 上执行此操作,但不能在两者上(在“g”上)。所以,我想知道这是否可行。
单击后,我还想从该图例元素中检索文本/类别,因为我需要重新分配
colorScale()
中的原始颜色。
以snippet为例,我想点击“legend”类的“g”,同时获取附加到rect元素的文本。
任何建议将不胜感激。
【问题讨论】:
【参考方案1】:如果将数据绑定到<g>
元素上,点击矩形和点击文本其实没有区别。在这两种情况下,您都可以检索数据。
但是,因为我们将使用一个名为 clicked
的属性...
legend.each(function(d)
d.clicked = false;
)
...为了处理点击,最好的办法是更改绑定到对象数组的数据:
var legend = svg.selectAll('.legend') // NEW
.data(dataset)
相应地更改矩形和文本,以使用d.label
。
那么,在点击函数中,我们就这样做了:
legend.on("click", function(d)
d.clicked = !d.clicked;
console.log("Category is: " + d.label)
path.filter(function(e)
return e.data.label === d.label
).style("opacity", d.clicked ? 0 : 1)
)
其中:
-
切换
clicked
属性;
根据标签过滤路径;
根据clicked
属性设置它们的样式。
这是更改后的代码:
var dataset = [
label: 'Abulia',
count: 10
,
label: 'Betelgeuse',
count: 20
,
label: 'Cantaloupe',
count: 30
,
label: 'Dijkstra',
count: 40
];
var width = 360;
var height = 360;
var radius = Math.min(width, height) / 2;
var donutWidth = 75;
var legendRectSize = 18; // NEW
var legendSpacing = 4; // NEW
var color = d3.scaleOrdinal(d3.schemeCategory20b);
var svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + (width / 2) +
',' + (height / 2) + ')');
var arc = d3.arc()
.innerRadius(radius - donutWidth)
.outerRadius(radius);
var pie = d3.pie()
.value(function(d)
return d.count;
)
.sort(null);
var path = svg.selectAll('path')
.data(pie(dataset))
.enter()
.append('path')
.attr('d', arc)
.attr('fill', function(d, i)
return color(d.data.label);
);
var legend = svg.selectAll('.legend') // NEW
.data(dataset) // NEW
.enter() // NEW
.append('g') // NEW
.attr('class', 'legend')
.style("cursor", "pointer")
// NEW
.attr('transform', function(d, i) // NEW
var height = legendRectSize + legendSpacing; // NEW
var offset = height * color.domain().length / 2; // NEW
var horz = -2 * legendRectSize; // NEW
var vert = i * height - offset; // NEW
return 'translate(' + horz + ',' + vert + ')'; // NEW
); // NEW
legend.append('rect') // NEW
.attr('width', legendRectSize) // NEW
.attr('height', legendRectSize) // NEW
.style('fill', function(d)
return color(d.label)
) // NEW
.style('stroke', function(d)
return color(d.label)
); // NEW
legend.append('text') // NEW
.attr('x', legendRectSize + legendSpacing) // NEW
.attr('y', legendRectSize - legendSpacing) // NEW
.text(function(d)
return d.label;
); // NEW
legend.each(function(d)
d.clicked = false;
)
legend.on("click", function(d)
d.clicked = !d.clicked;
console.log("Category is: " + d.label)
path.filter(function(e)
return e.data.label === d.label
).style("opacity", d.clicked ? 0 : 1)
)
.as-console-wrapper max-height: 10% !important;
<script src="https://d3js.org/d3.v4.min.js"></script>
【讨论】:
以上是关于是否可以通过单击 <g> 来选择 <path>?的主要内容,如果未能解决你的问题,请参考以下文章
在 Knockout.js 中单击按钮时检查选择控件是不是具有值