我正在绘制纽约地图(交互式svg),需要用数千个点覆盖它。使用this tutorial我几乎可以达到我想要的效果:有一个叠加层,点可见。
然而,尽管在svg中使用相同的投影和画布并且具有相同的宽度和高度,但是点与svg边界偏移了一些特定的数量:
即使通过调整大小,此偏移仍然存在,我无法得到错误的位置。 以下是我的代码片段:
var projection = d3.geoMercator()
.center([-73.98, 40.72])
.scale(width * 74)
.translate([(width) / 2, (height) / 2]);
...
var svg = d3.select("#svg-container")
.append("svg")
.attr("class", "map");
// CANVAS PART
var foreignObject = svg.append("foreignObject")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height)
.attr("class", "overlay");
// add embedded body to foreign object
var foBody = foreignObject.append("xhtml:body")
.style("margin", "0px")
.style("padding", "0px")
.style("background-color", "none")
.style("width", width + "px")
.style("height", height + "px");
// add embedded canvas to embedded body
var canvas = foBody.append("canvas")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height);
var context = canvas.node().getContext("2d");
// Points
context.clearRect(0, 0, width, height);
context.globalAlpha = .8;
userpoints.forEach(function(d, i) {
var crd = projection([d.lat, d.lon]);
// console.log(crd, );
context.beginPath();
context.rect(crd[0], crd[1], 1, 1);
context.fillStyle=comm_colors[d.Community];
context.closePath();
context.fill();
以下是生成的DOM的相应部分:
<svg class="map">
<foreignObject x="0" y="0" width="1036.962" height="1010" class="overlay" style="visibility: visible;">
<body style="margin: 0px; padding: 0px; width: 1036.96px; height: 1010px;">
<canvas x="0" y="0" width="1036.962" height="1010"></canvas>
</body>
</foreignObject>
<g id="boros"></g>
<g id="cts">
<path> ...
</path>
</g>
<defs>
<pattern id="lzssi" patternUnits="userSpaceOnUse" width="3" height="3"><rect width="3" height="3" fill="grey"></rect><path d="M 0,3 l 3,-3 M -0.75,0.75 l 1.5,-1.5
M 2.25,3.75 l 1.5,-1.5" stroke-width="0.5" shape-rendering="auto" stroke="white" stroke-linecap="square"></path>
</pattern>
</defs>
</svg>