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)"; })
在这个基于流星的 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)"; })