2013-07-25 3 views
2

d3에서 전환을 탐색하기 시작하면서 무엇이 데이터를 함께 사용하는지 실제로 알지 못하는지, 점점 더 편안 해지고 있습니다.d3 circle pack, 필터를 어떻게 변경합니까?

나는 구체적인 예를 일하고 있어요, http://bl.ocks.org/mbostock/4063269 버블 차트 : 나는 시간이 지남에 따라 인구 증가를 나타 내기 위해 그 용도를 변경하기 위해 노력하고있어

enter image description here

. 여기에 멋진 물건을 많이하지 않고 내 JSON

{ 
"name":"Population over Time", 
"children":[ 
    { 
    "name": "1790", 
    "children": [ 
     {"locID":"1","name": "New York city, NY", "size": 33131}, 
     {"locID":"2","name": "Philadelphia city, PA", "size": 28522}, 
     {"locID":"3","name": "Boston town, MA", "size": 18320}, 
     {"locID":"4","name": "Charleston city, SC", "size": 16359}, 
     {"locID":"5","name": "Baltimore town, MD", "size": 13503}, 
     {"locID":"6","name": "Northern Liberties township, PA", "size": 9913}, 
     {"locID":"7","name": "Salem town, MA", "size": 7921}, 
     {"locID":"8","name": "Newport town, RI", "size": 6716}, 
     {"locID":"9","name": "Providence town, RI", "size": 6380}, 
     {"locID":"10","name": "Marblehead town, MA", "size": 5661}, 
     {"locID":"11","name": "Southwark district, PA", "size": 5661}, 
     {"locID":"12","name": "Gloucester town, MA", "size": 5317}, 
     {"locID":"13","name": "Newburyport town, MA", "size": 4837}, 
     {"locID":"14","name": "Portsmouth town, NH", "size": 4720}, 
     {"locID":"15","name": "Sherburne town (Nantucket), MA", "size": 4620}, 
     {"locID":"16","name": "Middleborough town, MA", "size": 4526}, 
     {"locID":"17","name": "New Haven city, CT", "size": 4487}, 
     {"locID":"18","name": "Richmond city, VA", "size": 3761}, 
     {"locID":"19","name": "Albany city, NY", "size": 3498}, 
     {"locID":"20","name": "Norfolk borough, VA", "size": 2959}, 
     {"locID":"21","name": "Petersburg town, VA", "size": 2828}, 
     {"locID":"22","name": "Alexandria town, VA", "size": 2748}, 
     {"locID":"23","name": "Hartford city, CT", "size": 2683}, 
     {"locID":"24","name": "Hudson city, NY", "size": 2584} 
     ] 
    }, 
    { 
    "name": "1800", 
    "children": [ 
     {"locID":"1","name": "New York city, NY", "size": 60515}, 
     {"locID":"2","name": "Philadelphia city, PA", "size": 41220}, 
     {"locID":"25","name": "Baltimore city, MD", "size": 26514}, 
     {"locID":"3","name": "Boston town, MA", "size": 24937}, 
     {"locID":"4","name": "Charleston city, SC", "size": 18824}, 
     {"locID":"6","name": "Northern Liberties township, PA", "size": 10718}, 
     {"locID":"11","name": "Southwark district, PA", "size": 9621}, 
     {"locID":"7","name": "Salem town, MA", "size": 9457}, 
     {"locID":"9","name": "Providence town, RI", "size": 7614}, 
     {"locID":"20","name": "Norfolk borough, VA", "size": 6926}, 
     {"locID":"8","name": "Newport town, RI", "size": 6739}, 
     {"locID":"13","name": "Newburyport town, MA", "size": 5946}, 
     {"locID":"18","name": "Richmond city, VA", "size": 5737}, 
     {"locID":"26","name": "Nantucket town, MA", "size": 5617}, 
     {"locID":"14","name": "Portsmouth town, NH", "size": 5339}, 
     {"locID":"12","name": "Gloucester town, MA", "size": 5313}, 
     {"locID":"27","name": "Schenectady city, NY", "size": 5289}, 
     {"locID":"19","name": "Albany city, NY", "size": 5289}, 
     {"locID":"10","name": "Marblehead town, MA", "size": 5211}, 
     {"locID":"28","name": "New London city, CT", "size": 5150}, 
     {"locID":"29","name": "Savannah city, GA", "size": 5146}, 
     {"locID":"30","name": "Alexandria town, DC", "size": 4971}, 
     {"locID":"16","name": "Middleborough town, MA", "size": 4458}, 
     {"locID":"31","name": "New Bedford town, MA", "size": 4361}, 
     {"locID":"32","name": "Lancaster borough, PA", "size": 4292}, 
     {"locID":"17","name": "New Haven city, CT", "size": 4049}, 
     {"locID":"33","name": "Portland town, ME", "size": 3704}, 
     {"locID":"24","name": "Hudson city, NY", "size": 3664}, 
     {"locID":"23","name": "Hartford city, CT", "size": 3523}, 
     {"locID":"21","name": "Petersburg town, VA", "size": 3521}, 
     {"locID":"34","name": "Washington city, DC", "size":}, 
     {"locID":"35","name": "Georgetown town, DC", "size": 2993}, 
     {"locID":"36","name": "York borough, PA", "size": 2503} 
     ] 
    } 
    ] 
} 

, 난이 날은 특정 연도 보여주는로드 할 필터를 한 조정, 연간 데이터의 특정 세트를 보여주는 시작할 수 있었지만했습니다 이것이 잘못된 방법 인 것처럼 보입니다. 필터를 수동으로 다음 연도로 변경하면 1800 년 동안 만 거품이 표시되지만, 여전히 1790 거품을로드하려고 시도한 것처럼 가운데에 공백이 있기 때문입니다.

var node = svg.selectAll(".node") 
     .data(bubble.nodes(classes(root)) 
     .filter(function(d) { 
     if(d.depth == 1 && d.packageName == year){ 
      return d; 
     } 
     else{ 
      return null; 
     } 
     })) 
    .enter().append("g") 
     .attr("class", "node") 
     .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); 

나는 또한 사람들이 년 사이를 전환 할 수 있도록하는 JS 명령을 사용하여 해당 필터를 변경하는 방법을 찾는 힘든 시간을 보내고 있습니다. 아무도 나를 조금 더 잘 이해할 수있게 도와 줄 수 있습니까?

답변

2

문제는 레이아웃을 만들 때 모든 거품의 위치가 결정된다는 점입니다. 모든 것을 추가 할 때가 아닙니다. 1800 점에 대해서만 거품을 만들려면 레이아웃을 적용하기 전에 데이터를 필터링해야합니다. 거품을로드하려고하는 것이 아니라 bubble.nodes에 전달한 데이터의 일부였습니다. (특히,) 루트 (수업을 통과시켰다.

당신은 거품 형 차트의 예에서 .classes() 함수 내에서 자바 스크립트 .filter 방법을 사용하여이 작업을 수행 할 수 있습니다. 나는 단지 디스플레이로 변경할 경우 다음

은 예입니다 layout 패키지의 클래스 :

// Returns a flattened hierarchy containing all leaf nodes under the root. 
function classes(root) { 
    var classes = []; 

    function recurse(name, node) { 
    if (node.children) node.children.forEach(function(child) { recurse(node.name, child); }); 
    else classes.push({packageName: name, className: node.name, value: node.size}); 
    } 

    recurse(null, root); 
    classes = classes.filter(function(thisClass){return thisClass.packageName == 'layout'}) 
    return {children: classes}; 
} 

또한 그것이 내가 원하는 아닌지 말한다 각 요소에 대한 부울을 반환, 필터 기능 내가 원하는 요소를 반환하지 않습니다 또한 아무튼 '. 사용 된 배열을 수정하지 마십시오. classes == classes.filter()이 필요합니다.

내가 거품 형 차트의 예를 원래의 버블 차트에서 here.

의 작업 바이올린을 구축, 필터는 다른 원 뒤에 표시되는 일부 동그라미를 제거합니다.

EDIT (질문에 대한 답변) : 하나의 data 객체의

스토어 모든 데이터. 특정 연도의 내부 필터를 포함하는 classes 함수의 수정 된 버전을 사용할 수 있습니다. (필자가 예로 든 packageName에 필터링을 수행 한 것과 비슷합니다.) 업데이트하려면 모든 노드를 선택하고 다음 그들에 새 데이터를 입력이 자동으로 단지 기본 데이터 구조를 변경하여 노드, 단지 모든 데이터를 업데이트하지 않습니다

d3.selectAll('.node').data(bubble.nodes(modifiedClasses(root,year)) 

참고. 그런 다음 표준 d3 입력/종료/업데이트 패턴을 사용하여 시각화를 변경합니다.이 구조의 가장 좋은 예는 this block.입니다. 위치를 구별하기 위해 키 데이터를 사용하는 것이 좋습니다. 사용하는 경우

.data(bubble.nodes(modifiedClasses(root,year)),function(d){return d.locID}) 

각 요소는 특정 위치에 해당합니다. 이렇게하면 모든 데이터 요소를 제거한 다음 다시 작성하는 대신 새 날짜에 존재하지 않는 위치 (일부 .exit() 동작)를 제거하고 새로운 위치 (.enter() 포함)를 추가하고 두 해 모두 존재한다. 이렇게하는 방법에 대한 좋은 예는 일반적인 업데이트 시리즈 (위에 링크 된 블록)의 다음 두 블록을 확인하십시오. 알아낼 수 있다면 d3에서 데이터 조작의 기본 작업을 잘 처리 할 수 ​​있습니다.

+0

귀하의 예는 필터링 방법에 적용됩니다. 제 질문은, (내 JSON에서) 방아쇠를 당겨서 1800 년에 버튼을 눌렀다가 그걸 표시하는 것입니다. 그것은 필터가 데이터를로드 할 수있는 것, 지금은 그 데이터가 표시되는 방법이 필요합니다. 사람들이 새해를 선택할 때 버블 차트를 새 필터로 거의 재설정하고 싶습니다. –

+0

업데이트 된 답변보기 – ckersch

+0

이것은 완벽 해 보인다. 감사합니다! –

관련 문제