过滤路径并添加文字

时间:2019-03-26 10:07:10

标签: javascript d3.js

我想在路径上设置过滤器并附加文本,但是什么也没发生。

var filteredElements = svgContainer.selectAll("path")
                //.data(feat.features)
                .append("text")
                .filter(function (d) {
                    if (d.properties.myID > 0) {
                        return true;
                    };
                })

                .attr("x", function (d) {
                    return path.centroid(d)[0];
                })
                .attr("y", function (d) {
                    return path.centroid(d)[1];
                })
                .attr("text-anchor", "middle")
                .attr("font-size", "2px")
                .text("foo");

filteredElements包含46个正确的元素,但未附加文本。

使用该代码,它可以正常工作,但我需要过滤器中的条件:

svgContainer.selectAll("path[PE='1442']")
                .data(feat.features)
                .enter().append("text")
                .attr("x", function (d) {
                    return path.centroid(d)[0];
                })
                .attr("y", function (d) {
                    return path.centroid(d)[1];
                })
                .attr("text-anchor", "middle")
                .attr("font-size", "2px")
                .text("foo");

2 个答案:

答案 0 :(得分:2)

我将其添加为第二个答案,因为注释中没有足够的空间,但是它本身就足够了。

您在svg上绘制了路径,并且想要为这些路径的子集绘制文本。

有两种方法可以用于此目的。一种是使用父Module Module1 Sub Main() Dim dt As New DataTable dt.Columns.Add(New DataColumn("DateColumn", GetType(String))) dt.Rows.Add() Dim testDate = dt(0).Item(0) Dim setDate As DateTime? = Nothing 'Doesn't work setDate = If(testDate Is DBNull.Value, Nothing, CDate(testDate)) 'Works 'If testDate Is DBNull.Value Then ' setDate = Nothing 'Else ' setDate = CDate(testDate) 'End If 'Also works 'setDate = If(testDate Is DBNull.Value, Nothing, CType(testDate, DateTime?)) 'This works too 'setDate = If(testDate Is DBNull.Value, Nothing, testDate) 'Working 'setDate = IIf(testDate Is DBNull.Value, Nothing, testDate) If setDate IsNot Nothing Then Console.WriteLine("Why does setDate = '" & setDate.ToString & "' ?!") End If Console.ReadKey() End Sub End Module 元素同时包含路径和文本:

g

绑定的数据将传递给子级,允许您在添加子级文本之前过滤父级选择。

另一种方法更接近于您已经完成的工作,但是您并没有惯用的d3。我们也不需要将数据重新绑定到路径(// Append a parent: var g = svg.selectAll(null) // we want to enter an element for each item in the data array .data(features) .enter() .append("g"); // Append the path g.append("path") .attr("d",path) .attr("fill", function(d) { ... // etc. // Append the text to a subset of the features: g.filter(function(d) { return d.properties.myID > 0; // filter based on the datum }) .append("text") .text(function(d) { .... // etc. ),而是可以使用:

d3.selectAll("path").data(

顺便说一句,您的初始方法存在问题:

  • 它将文本直接附加到路径元素,而不会呈现(如您所述)
  • 它再次将数据绑定到路径,对于所选内容中的每个元素,您都将数据数组的一项绑定到所选元素-因为所选内容是路径的子集,但是数据是完整数据集,您可能会为每个路径分配不同的数据(在未指定标识符的情况下,完整数据集中的第svgContainer.selectAll(null) .data(feat.features.filter(function(d) { return d.properties.myID > 0; })) .enter() .append("text") .attr("x", path.centroid(d)[0]) .attr("y", path.centroid(d)[1]) .attr("text-anchor", "middle") .attr("font-size", "2px") .text("foo") 个项目绑定到子选择中的第i个元素)。

答案 1 :(得分:0)

我想我现在有一个解决方案。我的文本节点在我的路径节点内。现在,我只是在if条件下执行此操作,然后在路径下添加文本节点。

svgContainer.selectAll("path")
                .data(feat.features)
                .filter(function (d) {
                    if (d.properties.myID > 0) {
                        d3.select("svg")
                            .append("text")
                            .attr("x", path.centroid(d)[0])
                            .attr("y", path.centroid(d)[1])
                            .attr("text-anchor", "middle")
                            .attr("font-size", "2px")
                            .text("foo")
                    };
                })