【发布时间】:2017-12-21 03:56:20
【问题描述】:
我正在尝试绘制单个数据点以及在这些点之间运行的线路径,例如我之前得到帮助的示例 D3 stop and restart transition along path to allow click through to geo data coordinates。
现在我想使用我的实际数据而不是一组测试坐标,但我遇到了麻烦。我已经为我的数据尝试了 geoJson 文件和 csv 文件。我正在使用带有 lon 和 lat 的 csv 文件作为点,并希望从同一组数据中创建线,即使用一组数据作为点和线。
我无法让我的线路显示在正确的位置 - 它在右上角,但应该在/通过点。我认为这与投影有关,但我无法正确解析数据以获取所需的行字符串。我尝试在这里使用示例https://bl.ocks.org/alandunning/cfb7dcd7951826b9eacd54f0647f48d3 - 但是得到空对象??
我的问题是如何将 csv lon lat 与 d3 svg 线生成器一起使用。 这是我的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Working version 3</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-array.v1.min.js"></script>
<script src="https://d3js.org/d3-geo.v1.min.js"></script>
<script src="https://d3js.org/d3-queue.v3.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<style type="text/css">
circle {
fill: steelblue;
stroke: pink;
stroke-width: 3px;
}
.line{
fill: none;
stroke: red;
stroke-width: 6;
}
</style>
</head>
<body>
<script>
var w = 960,
h = 500;
var projection = d3.geoMercator()
.translate([w/2, h/2])
.scale([w * 0.16]);
var path = d3.geoPath()
.projection(projection);
var duration = 10000;
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h);
/*
var line = d3.line()
.x(function (d) {return projection([d.lon]);})
.y(function (d) {return projection([d.lat]);})
.curve(d3.curveBasis);
var line = d3.line()
.x(function(d){return projection(d[0].lon);})
.y(function(d){return projection(d[0].lat);})
.curve(d3.curveBasis);
/*ok line shows up but in wrong place
var line = d3.line()
.x(function(d) { return (d.lon); })
.y(function(d) { return (d.lat); })
.curve(d3.curveBasis);
*/
var line = d3.line()
.x(function(d) { return (d.lon); })
.y(function(d) { return (d.lat); })
.curve(d3.curveBasis);
//original
/*
var line = d3.line()
.x(function(d){return projection(d)[0];})
.y(function(d){return projection(d)[1];})
.curve(d3.curveBasis);
*/
//
//bring in data
d3.queue()
.defer(d3.json, "data/oceans.json")
.defer(d3.csv, "data/speckCities.csv")
.await(ready);
function ready (error, oceans, data){
if (error) throw error;
//console.log(data[0]);
//console.log(data[0].lon);
//map
svg.selectAll("path")
.data(oceans.features)
.enter()
.append("path")
.attr("d", path)
.style("fill", "#A8B2C3");
var linepath = svg.append("path")
.datum(data)
.attr("d", line)
.attr('class', 'line');
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d.lon, d.lat])[0];
})
.attr("cy", function(d) {
return projection([d.lon, d.lat])[1];
})
.attr("r", 5)
.style("fill", "yellow")
.style("stroke", "gray")
.style("stroke-width", 0.25)
.style("opacity", 0.75)
.append("title") //Simple tooltip
.text(function(d) {
return d.name ;
});
//
//
/*svg.selectAll(".point")
.data(coordinates)
.enter()
.append("circle")
.attr("r", 7)
.attr("transform", function(d) { return "translate(" + projection(d) + ")"; });
var circle = svg.append("circle")
.attr("r", 19)
.attr("transform", "translate(" + projection(d) + ")");
/*
var pauseValues = {
lastT: 0,
currentT: 0
};
function transition() {
circle.transition()
.duration(duration - (duration * pauseValues.lastT))
.attrTween("transform", translateAlong(linepath.node()))
.on("end", function(){
pauseValues = {
lastT: 0,
currentT: 0
};
transition()
});
}
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {
t += pauseValues.lastT;
var p = path.getPointAtLength(t * l);
pauseValues.currentT = t;
return "translate(" + p.x + "," + p.y + ")";
};
};
}
d3.select('button').on('click',function(d,i){
var self = d3.select(this);
if (self.text() == "Pause"){
self.text('Play');
circle.transition()
.duration(0);
setTimeout(function(){
pauseValues.lastT = pauseValues.currentT;
}, 100);
}else{
self.text('Pause');
transition();
}
});
*/
}
</script>
</body>
</html>
【问题讨论】: