我有一个项目,我们通过他们的纬度/长度将圆圈固定在世界地图上。每个圆圈应该是/ has / include / show a image:hasTheThing.png或doesNotHaveTheThing.png。随着应用中的条件发生变化,哪些圈子会改变哪些图像并需要动态更新。
现在我的代码如下。
var defs = pointClustersG.append("defs");
defs.append('pattern')
.attr("id", "hasTheThing")
.attr("patternUnits", "userSpaceOnUse")
.attr("width", "10px")
.attr("height", "10px")
.append("svg:image")
.attr("xlink:href", "images/hasTheThing.png")
.attr("width", "10px")
.attr("height", "10px")
.attr("x", 0)
.attr("y", 0);
defs.append('pattern')
.attr("id", "doesNotHaveTheThing")
.attr("patternUnits", "userSpaceOnUse")
.attr("width", "10px")
.attr("height", "10px")
.append("svg:image")
.attr("xlink:href", "images/doesNotHaveTheThing.png")
.attr("width", "10px")
.attr("height", "10px")
.attr("x", 0)
.attr("y", 0);
var point = pointClustersG.selectAll("circle")
.data(allPointClusters)
.enter()
.append("circle")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("id", function(d) { return d.id; })
.attr("class", "pointCluster")
.attr("r", "5px")
.attr("fill", function(d) { if(d.hasTheThing) { return "url(#hasTheThing)"} else { return "url(#doesNotHaveTheThing)"}});
无论我对x,y,高度,宽度和r值做什么,图案都会在圆圈内重复出现。但它在每个圆圈中重复的方式不同,这使我相信这不仅仅是不能正确地确定位置和尺寸。想知道我的代码是否错误,或者它是否是我的整体方法。如果它是选项2,那么任何人都有关于如何更好地做到这一点的建议吗?
答案 0 :(得分:1)
经验表明,找到解决问题的最佳方法是:
不确定这对任何不是我的人有多大用处,但以防它可以提供帮助:
var points = pointClustersG.selectAll("image")
.data(allPointClusters)
.enter()
.append("svg:image")
.attr("xlink:href", "images/doesNotHaveTheThing.png")
.attr("width", "10px")
.attr("height", "10px")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("id", function(d) { return d.id; })
.attr("class", "pointMarker");
创建以下HTML:
<image href="images/doesNotHaveTheThing.png" width="10px" height="10px" x="695.1694728311688" y="625.5607912558139" id="3480" class="pointMarker"></image>
由于我使用js / jquery和朋友来决定哪个点需要什么图像,我只是同时更改href值。
答案 1 :(得分:1)
我看到你给自己写了一个答案,这很好,你有权利。但是,只是为了解释一下,你的问题......
......图案在圆圈内重复。
...可以通过将<pattern>
的宽度和高度设置为1并删除userSpaceOnUse
来修复:
defs.append('pattern')
.attr("id", "hasTheThing")
.attr("width", 1)
.attr("height", 1)
//etc...
根据Docs:
与上面使用的gradientUnits属性一样,模式也有一个属性patternUnits,它指定这些属性将采用的单位。默认为“objectBoundingBox”,如上所述,因此值为1 会缩放到您应用该模式的对象的宽度/高度。 (强调我的)
使用部分代码检查此演示:
var svg = d3.select("svg");
var defs = svg.append("defs");
defs.append('pattern')
.attr("id", "hasTheThing")
.attr("width", 1)
.attr("height", 1)
.append("svg:image")
.attr("xlink:href", "http://www.pressunion.org/wp-content/uploads/2016/11/1-2.jpg")
.attr("width", 140)
.attr("height", 140)
.attr("y", -30)
.attr("x", -20);
defs.append('pattern')
.attr("id", "doesNotHaveTheThing")
.attr("width", 1)
.attr("height", 1)
.append("svg:image")
.attr("xlink:href", "https://s-media-cache-ak0.pinimg.com/736x/92/9d/3d/929d3d9f76f406b5ac6020323d2d32dc.jpg")
.attr("width", 120)
.attr("height", 120)
.attr("x", -20)
.attr("y", -10);
var circles = svg.selectAll("foo")
.data(d3.range(5))
.enter()
.append("circle");
circles.attr("cy", 60)
.attr("cx", function(d) {
return 50 + 90 * d
})
.attr("r", 40)
.attr("stroke", "#222")
.attr("stroke-width", 3)
.attr("fill", function(d) {
return d % 2 === 0 ? "url(#hasTheThing)" : "url(#doesNotHaveTheThing)"
});
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500"></svg>