2014-02-11 6 views
0

내가 여기에 명시된 테이트 컬렉션에서 데이터로 작업하고있어이 : https://github.com/tategallery/collectiond3.nest() 둥지 배열 요소 (생성 중복)

나는 운동 그룹에 예술가를 시도하고있다. 아티스트의 모든 JSON 객체에는 "movements"라는 속성이 있습니다.이 요소는 0 개 이상의 요소로 구성된 배열입니다. 예를 들어

, 비토 아콘 ​​치는 개념 예술과 공연 예술과 관련된 :

"movements": [ 
    { 
     "era": { 
     "id": 415, 
     "name": "20th century post-1945", 
     "workCount": 3604 
     }, 
     "id": 421, 
     "name": "Conceptual Art", 
     "workCount": 478 
    }, 
    { 
     "era": { 
     "id": 415, 
     "name": "20th century post-1945", 
     "workCount": 3604 
     }, 
     "id": 436, 
     "name": "Performance Art", 
     "workCount": 81 
    } 
] 

는 지금은 이상적() d3.nest를 사용하여, 자신의 운동 그룹에 예술가를 원한다. 문제는 여러 움직임과 관련된 아티스트를 어떻게 처리합니까? 나는 그들이 모든 관련 운동에 한번 나타나기를 바랄 것이다. http://jsfiddle.net/jwFZV/

+0

그것은 내가 원하는 출력이다 : http : // jsfiddle.net/fEyZ6/5/ 최적화 할 수 있습니까? – Florian

+0

d3.nest()를 사용하여이를 구현하는 방법이있을 수 있지만 들어 본 적이 없습니다. 솔루션을 답으로 게시해야합니다. 그것을 공유 주셔서 감사합니다 :) –

답변

0

이렇게 그것을 해결 : 여기서

데이터의 발췌와 JSFiddle이다 http://jsfiddle.net/fEyZ6/6/

I 실제로 d3.nest (의해 제공된 것)과는 다른 구조가 필요하므로이 체격 더 의미가 있습니다.

좀 더 복잡 할 수도 있지만 문자열 속성이나 개체 배열을 사용하여 재구성 할 수 있어야합니다. 배열 키로 개체 속성을 선택하기 위해 식별자를 사용하고 있습니다. 지도를 사용하여 생각했지만 객체를 변경하고 있으므로 키가 일치하지 않습니다.

최적화 제안은 여전히 ​​환영합니다.

var Hierarchy = function(data, accessor) { 

    var data = data, 
     accessor = accessor, 
     identifier = "name", 
     hierarchy = false, 
     rebuild = false; 

    this.hierarchy = function() { 

     if(hierarchy && !rebuild) { 
      return hierarchy; 
     } 

     hierarchy = []; 
     var keys = []; 

     if(!accessor) { 
      console.log("ERROR no accessor for hierarchy"); 
      return false; 
     } 


     for (var i in data) { 

      var parents = accessor.call(data, data[i]); 

      if(Object.prototype.toString.call(parents) != "[object Array]") { 

       parents = [parents]; 

      }; 

      parents.forEach(function(element) { 

       if(typeof element === "object") { 

        p = keys[element[identifier]]; 

       } else { 

        p = keys[element]; 

       } 

       if (!p) { 

        p = { 
         element: element, 
         children: [] 
        }; 
       } 

       p.children.push(data[i]); 


       if(typeof element === "object") { 

        keys[element[identifier]] = p; 

       } else { 

        keys[element] = p; 

       } 

      }) 


     } 

     for (var i in keys) { 

      if(typeof keys[i].element != "object") { 
       keys[i].element = { 
        name: keys[i].element 
       } 
      } 

      keys[i].element.children = keys[i].children; 
      hierarchy.push(keys[i].element); 

     } 

     rebuild = false; 

     return hierarchy; 
    } 

    // accessors 
    this.data = function(_) { 
     if(!arguments.length) return data; 
     data = _; 
     rebuild = true; 
    }; 

    this.identifier = function(_) { 
     if(!arguments.length) return identifier; 
     identifier = _; 
     rebuild = true; 
    }; 

    this.accessor = function(_) { 
     if(!arguments.length) return accessor; 
     accessor = _; 
     rebuild = true; 
    }; 


} 
0

데이터가 이미 중첩되어있어 문제입니다.

https://github.com/mbostock/d3/wiki/Arrays#wiki-d3_pairs (d3.pairs 이후)의 예제를 확인하십시오.

이 예제는 3 개의 비슷한 오브젝트로 구성된 플랫 데이터 세트로 시작하고 중첩 된 후 오브젝트는 동시에 여러 그룹에 속하도록 복제됩니다. 이것은 객체가 new로 생성되는 대신 참조되기 때문에 사전 중첩 된 JSON 객체보다 훨씬 다양합니다.

데이터 세트에서 움직임은 여러 아티스트가되도록 복제되지만 두 아티스트가 동일한 움직임을 갖는 경우 ==를 사용하여 비교할 수 없습니다. 항상 false를 반환합니다.

또 다른 접근법은 각 개체 컬렉션 (아티스트, 동작 ...)을 자체 개체 배열로 보내는 것입니다. 개체는 몇 가지 주요 속성 또는 관련 개체의 인덱스 목록을 통해 다른 개체와의 관계를 표시 할 수 있습니다.

테이블 접근 방식을 사용하면 CSV 또는 TSV로 클라이언트에 데이터를 보낼 수 있습니다. 거대한 데이터 세트를 다루는 경우 오브젝트 키가 차지하는 공간의 양을 알 수 있으며 각 오브젝트에 대해 동일합니다. 테이블 헤더가이 문제를 해결합니다. 정수와 문자열 값을 처리 할 때 훨씬 더 눈에 띄게됩니다.

시작하려면 중복 된 개체를 제거하고 다른 데이터 형식을 분리해야합니다. 이것은 당신에게 훨씬 청결한 출발점을 줄 것입니다.

다음은 몇 가지 권총 모양의 발췌문입니다. 그들은 작동한다

var artists = data; 

var movements = data.reduce(function(object, artist){ 
    artist.movements = artist.movements.map(function(movement){ 
    object[movement.id] = object[movement.id] || movement; 
    return movement.id; 
    }).join(','); 
    return object; 
},{}); 

var eras = d3.values(movements).reduce(function(object, movement){ 
    var eid = movement.era.id; 
    object[eid] = object[eid] || movement.era; 
    movement.era = eid; 
    return object; 
},{}); 
+0

매우 유효한 점, 감사합니다! 나는 원래의 데이터 세트가 실제로 관계형 테이블의 세트라고 생각하지만, 그것을 아티스트의 JSON 객체로 드러내기로 결정했다. – Florian

+0

그게 보통의 경우, 사실, 그것은 꽤 많은 사람들이 직면하고있는 웹 앱의 목적입니다. 객체 관계를 저장하고 사용자가 무언가를 요청할 때 예쁜 웹 사이트를 렌더링합니다. 그러나 JSON을 출력하는 경우에는 JSON 소비자가 이해할 수있는 방식으로 처리해야하며 객체 관계를 가짜로 만들어 데이터를 상당히 세밀하게 처리하지 않아야합니다. – Julian