2017-12-21 15 views
2

개별 데이터 포인트를 플롯하려하고 또한 이전에 도움을받은이 예제 D3 stop and restart transition along path to allow click through to geo data coordinates과 같이 이러한 포인트 사이에서 실행되는 라인 경로를 시도하고 있습니다.c3v 데이터에서 d3 라인 및 점

이제 테스트 세트가 아닌 실제 데이터를 사용하고 싶지만 문제가 발생합니다. geoJson 파일과 내 데이터에 대한 CSV를 모두 시도했습니다. 포인트에 대한 lon과 lat와 함께 csv 파일을 사용하고 있으며 동일한 데이터 세트에서 라인을 만들려고합니다. 즉 포인트와 라인에 대해 하나의 데이터 세트를 사용합니다.

내 라인이 올바른 위치에 나타나지 않을 수 있습니다. 오른쪽 상단에 있지만 온 포인트를 통과해야합니다. 이것은 투영과 관련이 있다고 생각하지만 필요에 따라 줄 문자열을 얻기 위해 데이터를 올바르게 파싱하는 데 문제가 있습니다. 여기 샘플을 사용하려고 시도했습니다 https://bl.ocks.org/alandunning/cfb7dcd7951826b9eacd54f0647f48d3 -하지만 빈 객체가 있습니까 ?? line in red points in yellow

제 질문은 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> 

답변

1

: 당신의 경도가/당신의 geojson 위도 쌍은 바로 픽셀로 변환이 경우

var linepath = svg.append("path") 
    .datum(data) 
    .attr("d", line) 
    .attr('class', 'line'); 

을 조정 :

var line = d3.line() 
    .x(function(d) { return (d.lon); }) 
    .y(function(d) { return (d.lat); }) 
    .curve(d3.curveBasis); 
이 내 코드입니다

svg 좌표는 왼쪽 상단의 [0,0]에서 시작하고 점은 동쪽으로 10도 정도 (양의 경도), 북쪽으로 50도 정도 (posi 두 번째 위도)에서 선의 첫 번째 점은 왼쪽에서 10 픽셀, 위쪽에서 50 픽셀 나타납니다. 또한 svg y 값이 아래로 내려감에 따라 증가하기 때문에 위도가 북쪽으로 이동하면 위도 값이 증가하기 때문에 (지도에서 대시 적으로 올라간다), 사용자의 선은 사용자의 점에 비해 y 축에서 뒤집어 보입니다. 투사 기능이 모두 반환됩니다, 그래서 당신은 점을 투사하는 위도와 경도 모두 필요

var line = d3.line() 
    .x(function(d) { return projection([d.lon,d.lat])[0] ; }) 
    .y(function(d) { return projection([d.lon,d.lat])[1]; }) 
    .curve(d3.curveBasis); 

:

당신은 x와 y 포인트를 설정하는 돌출부를 사용하도록 라인 기능을 설정할 수 있습니다 따라서 x와 y는 모두 [0]과 [1]이므로 주석 처리 된 섹션이 작동하지 않습니다.

그러나 이것은 필요하지 않습니다. 세계 배경으로), 즉 geojson에서 데이터를 사용할 수 있는지 (geojson을 th로 만드는 것은 어렵지 않지만 d3.line의 라인 사이의 직선 세그먼트 또는 직교 좌표 공간에서, 소정의 곡선을 따라 -이 라인보다 더 정확

var linepath = svg.append("path") 
    .datum(data) // in geojson form 
    .attr("d", path) // use your path 
    .attr('class', 'line'); 

: E) 플라이. d3.geoPath는 큰 원의 거리를 따르므로 점 사이의 세그먼트는 행성에서 가장 짧은 경로를 따르므로보다 정확한 표현이 가능하고 때로는 생각이 덜하고 문체가 적습니다.

이 데이터를 가정하는 것은 모양, 즉석에서 geojson를 만들려면 : [{lon:number,lat:number},{lon:number,lat:number}] 당신은 같은 것을 사용할 수 있습니다 상세한 답변을

var points = data.map(function(d) { return [d.lon,d.lat] }) 
var geojson = { "type": "LineString", "coordinates": points } 
+0

정말 감사합니다. 당신이 저를 위해 그런 세부 사항에 갔다 정말 좋습니다.나는 당신의 제안을 시도하고 그들은 내 문제에 대답을한다 - 나는 CSV lat에서 선 문자열을 만드는 법을 본다. 그러나 내가 얻는 선은 내가 원하는 것을 아니다. 나는 또 다른 질문을 올렸으므로 나를 다시 돕기를 바란다. 데이터의 json 버전이 있고 이것을 사용하는 것을 선호하지만 내 포인트를 선 스트링으로 변환하는 방법을 생각할 수 없습니다. 다시 한 번 감사드립니다 – user3471259

+0

사실 저는 이것에 대해 좀 더 연구했고 당신의 대답은 완벽합니다. 예상 한 결과를 보지 못한 이유는 단순히 내 데이터와 관련이있는 것입니다. 나는 geojson을 만들기 위해 몇몇 json을 성공적으로 사용했고 당신이 제안한 것처럼 투영했다. 도움을 주셔서 다시 한 번 감사드립니다. – user3471259

+0

문제 없으니 기꺼이 도와 드리겠습니다. –