是否可以通过单击 <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】:

如果将数据绑定到&lt;g&gt;元素上,点击矩形和点击文本其实没有区别。在这两种情况下,您都可以检索数据。

但是,因为我们将使用一个名为 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;
&lt;script src="https://d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;

【讨论】:

以上是关于是否可以通过单击 <g> 来选择 <path>?的主要内容,如果未能解决你的问题,请参考以下文章

在 Knockout.js 中单击按钮时检查选择控件是不是具有值

模拟右键单击图像

通过单击标签来切换 HTML 单选按钮

Wordpress:在jQuery按钮上,单击Contact Form 7菜单中的预选择选项

如何通过单击jQuery中的html表来添加任何行[重复]

无法单击Selenium IDE中弹出窗口中的按钮