我试图通过美国东北部的三个点进行按钮激活的d3缩放浏览,但我很难在视觉上显示数据(尽管在控制台中显示)。我是一个初级用户,通常可以解决问题,但这是我的头脑。
这是一个接近我试图做的例子:
在美国不同地点之间缩放: http://bl.ocks.org/mbostock/6242308
该示例不对数据进行样式设置,使用TopoJSON并使用画布进行缩放调用。我尝试使用GeoJSON进行缩放(因此我可以链接到CartoDB表)并对其进行样式设置。
我经历了很多事情,使这两件事都发生了,并且已经没有成功了。现在它出现了空白而且一直存在。我可以实时查看数据,但无法更改样式。
我在这里做错了什么?我确定它很简单,但需要轻推。
<!DOCTYPE html>
<html lang ="en">
<head>
<meta charset="utf-8">
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<style type="text/css">
canvas{
color: 'blue';
}
path.state {
color: 'red';
}
</style>
</head>
<body>
<script type="text/javascript">
var width = 960,
height = 500,
stateMap;
var sf = [-122.417, 37.775],
ny = [-74.0064, 40.7142];
var scale,
translate,
visibleArea, // minimum area threshold for points inside viewport
invisibleArea; // minimum area threshold for points outside viewport
var zoom = d3.behavior.zoom()
.size([width, height])
.on("zoom", zoomed);
var projection = d3.geo.mercator()
.translate([width/2, height/2])
.scale(500);
var canvas = d3.select("body").append("canvas")
.attr("width", width)
.attr("height", height);
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var context = canvas.node().getContext("2d");
var path = d3.geo.path()
.projection(simplify)
.context(context);
stateMap = d3.json("http://linepointpath.cartodb.com/api/v2/sql?format=GeoJSON&q=SELECT * FROM GRAPHstates", function(error, stateMap) {
console.log(stateMap)
canvas
svg.selectAll("path")
.data(stateMap.feature)
.enter().append("path")
.attr("class", "state")
.attr("d", path)
.call(zoomTo(sf, 4).event)
.transition()
.duration(60 * 1000 / 89 * 2)
.each(jump);
});
var simplify = d3.geo.transform({
point: function(x, y, z) {
if (z < visibleArea) return;
x = x * scale + translate[0];
y = y * scale + translate[1];
if (x >= -10 && x <= width + 10 && y >= -10 && y <= height + 10 || z >= invisibleArea) this.stream.point(x, y);
}
});
function zoomTo(location, scale) {
var point = projection(location);
return zoom
.translate([width / 2 - point[0] * scale, height / 2 - point[1] * scale])
.scale(scale);
}
function zoomed(d) {
translate = zoom.translate();
scale = zoom.scale();
visibleArea = 1 / scale / scale;
invisibleArea = 200 * visibleArea;
context.clearRect(0, 0, width, height);
context.beginPath();
path(d);
context.stroke();
}
function jump() {
var t = d3.select(this);
(function repeat() {
t = t.transition()
.call(zoomTo(ny, 6).event)
.transition()
.call(zoomTo(sf, 4).event)
.each("end", repeat);
})();
}
</script>
</body>
</html>
答案 0 :(得分:0)
我怀疑更大的问题是,当您前往的示例使用GeoJSON时,您正在使用TopoJSON。两者之间的差异可能会导致path
的呈现方式出现问题。
您遇到的另一个问题是,使用canvas
时,函数调用是不同的。您正在使用正常的svg
函数调用来附加SVG,绑定数据,然后对其进行样式设置。使用canvas
,您可以通过canvas context
object与元素进行互动。这与您尝试在代码中使用的标准SVG对象具有不同的语法和用法。如果您关注this tutorial,您会注意到她没有调用任何SVG功能,而是使用context
API来绘制canvas
元素的样式。请务必查看the working example of the code。
在您的情况下,这意味着您的代码在这里:
svg.selectAll("path")
.data(stateMap.feature)
.enter().append("path")
.attr("class", "state")
.attr("d", path)
.call(zoomTo(sf, 4).event)
.transition()
.duration(60 * 1000 / 89 * 2)
没有必要,也没有为你做任何事情。生成路径的代码使用zoomed()
对象嵌入context
函数:
context.clearRect(0, 0, width, height);
context.beginPath();
path(d);
context.stroke();
使用context
功能创建您尝试显示的对象。有一系列函数调用会产生这种行为,您需要打破链条以确保您在每一步都获得所需的内容。
如果您想使用GeoJSON,只需显示地图然后应用缩放功能即可。它可能会让你的生活变得更容易,最终迭代地构建你想要的可视化。
有关使用D3的canvas
和svg
之间差异的更多信息,包括对每个操作执行相同操作的示例,请检查此blogpost并祝好项目。