SVG ds.js - 为什么对 defs 的追加操作会修改 svg selectAll 的数据绑定

SVG ds.js - why does an append operation on defs modifies the data binding of svg selectAll

在这个基于流星的 d3 svg 应用程序中,设置了一个简单的绘图板。圆形工具用作主画笔。图案被添加到 svg 中。单击按钮将 selected 图案的 ID 加载到发送到 d3.svg 的参数,并进一步将图案添加到圆形工具。然后我想使用掩码向图案添加特定颜色,并且返回错误类型错误:"d" 未定义。 "d"是用于selectAll数据绑定的数据参数,在添加掩码之前没有报错。

在 d3 svg JS 客户端:

    Canvas = function() {
        var self = this;
        var svg;

        var createSvg = function() {
            svg = d3.select('#canvas').append('svg')
            .attr('width', window.innerWidth * 0.8)   //800
            .attr('height', window.innerHeight * 0.8);   //600
        };

        createSvg();

        self.clear = function() {
            d3.select('svg').remove();
            createSvg();
        };

        self.drawCircs = function(data) {
        if(data.length < 1) {
            self.clear();
            return;
        } 

        if (svg) {

            var defs = svg.append('defs');

                defs.append("mask")
                    .attr('id', "crayonMask")
                .append('ellipse')
                    .attr('cx', '0')
                    .attr('cy', '0')
                    .attr('rx', '100%')
                    .attr('ry', '100%')
                    .attr("fill-opacity", "0.3")
                    .attr('fill', "url(#crayon)");

                defs.append('pattern')
                    .attr('id', "crayon")  
                    .attr('patternUnits', "objectBoundingBox")
                    .attr('patternContentUnits', "userSpaceOnUse")
                    .attr('width', "36")
                    .attr('height', "16")
                .append('image')
                    .attr('xlink:href', "http://www.onlygfx.com/wp-content/uploads/2017/09/crayon-scribble-banner-2.png")
                    .attr('x', "0")
                    .attr('y', "0")
                    .attr('width', "36")
                    .attr('height', "16");

                 svg.selectAll('circle').data(data, function(d){ return d._id; }) 
                .enter().append('circle')
                .attr('cx', function(d){ return d.x; })
                .attr('cy', function(d){ return d.y; })
                .attr('r', function(d){ return d.w; })
                .attr("fill-opacity", function (d) { return d.o; })
                .attr('mask', "url(#" + d.ptrnId + "Mask)")   
                .attr('fill', function (d) {if(d.ptrnId === ""){ 
                    console.log("circle brush pattern selected!"); 
                    return d.c; 
                } else {
                        console.log(d.ptrnId + " brush pattern selected!"); 
                        return d.c;   //"url(#" + d.ptrnId + ")"; 
                    }})   
                ;

        }
    };
}

在基于用户的事件客户端: 作为参考,这是将数据对象发送到 d3 的方式。

var markPoint = function(event) {
  var offset = $("#canvas").offset();

  if(lastX == 0) {
    lastX = (event.pageX - offset.left);
    lastY = (event.pageY - offset.top);
  }

  points.insert({
    dateTime: new Date(),
    toolType: toolType,
    x: (event.pageX - offset.left),
    y: (event.pageY - offset.top),
    x1: lastX,
    y1: lastY,
    w: thickness,
    c: strokeColor,
    o: opacity,
    ptrnId: brushPattern

  });

    // updating last point
    lastX = (event.pageX - offset.left);
    lastY = (event.pageY - offset.top);
}

没有附加掩码,select 所有数据绑定都可以完美运行。输出是带有图案填充的圆形描边。但是在将掩码附加到 svg 上的 def 后,数据绑定 '(d)' returns 未定义。

我什至将掩码从圆形更改为椭圆形,以避免 select为 selectAll('circle') 使用掩码圆。

我已经被这个问题困扰了很长一段时间。该应用程序的其余部分基本上建立在几种模式上,但由于遮罩不起作用,一切都失败了。请帮帮我。

P.S。 - 这是我第一次在这里提问,所以请原谅问题结构不佳。

我认为您正在尝试访问字符串中的 d,而您应该这样做

.attr("mask", function(d) { return "url(#" + d.ptrnId + "Mask)"; })