2014-12-07 6 views
1

dc.js (crossfilter)로 악용중인 CSV 데이터 세트가 있습니다.교차 필터를 사용하여 간접 지정 필드를 여러 개 줄임

Date, Country 1,Country 2,Country 3,Country 4,Country 5,Country 6,Target country (...) 2014/12/11, USA, France, UAE, (...), Iraq

내가 할 노력하고 있어요 문제는 국가 별 한 행과 행 차트를 그릴 것입니다. 당신이 볼 수 있듯이 그것은 목록 배열에 의 순을 밀어하지 않습니다,

var countries = ndx.dimension(function(d) { 
    var list = []; 
    list.push(d["Country 1"]); 
    if (d["Country 2"]) {list.push(d["Country 2"]);}; 
    if (d["Country 3"]) {list.push(d["Country 3"]);}; 
    if (d["Country 4"]) {list.push(d["Country 4"]);}; 
    if (d["Country 5"]) {list.push(d["Country 5"]);}; 
    if (d["Country 6"]) {list.push(d["Country 6"]);}; 
    return list; 
    }); 
    var countriesGroup = countries.group().reduceSum(function(d) { 
    return d.totalNumberOfStrikes; 
    });; 
    countryChart 
    .width(400).height(500) 
    .group(countriesGroup) 
    .dimension(countries) 
    .ordering(function(d){ return -d.value }); 

그러나 : 여기에 오늘과 같은 내 솔루션입니다. CSV 행의 국가 조합마다 목록에 새 항목이 만들어지기 때문에 어리석은 결과가 발생합니다. 내가 원하는 무엇

는 각각의 고유 한 국가를 포함하는 목록이 다음 행 차트에 일을 음모하는 것입니다.

도와 주시겠습니까? 대단히 감사합니다!

답변

1
나중에 대화 in another question을 바탕으로

dc.js users group, 여기 그대로 데이터를 유지하는 더 나은 감소의 :

var strikingCountriesGroup = xScaleDimension.group().reduce(
    function(p, v) { // add 
     countryFields.forEach(function(c) { 
      if(v[c]) p[v[c]] = (p[v[c]] || 0) + v.totalNumberOfStrikes; 
     }); 
     return p; 
    }, 
    function(p, v) { // remove 
     countryFields.forEach(function(c) { 
      if(v[c]) p[v[c]] = p[v[c]] - v.totalNumberOfStrikes; 
     }); 
     return p; 
    }, 
    function() { // initial 
     return {}; 
    } 
); 

그 괄호의 큰 복잡하게 얽힌처럼 보일 수 있지만이 아이디어는 필드 v[c]입니다 여기서 c은 "국가 1", "국가 2"... 인 원본 데이터 집합에서 축소에서 만들려는 필드를 간접적으로 지정합니다.

우리는 값 v에서지도 p로 감소된다. 우리는 국가 필드를 통해 루프, 각 c에 대한, vc에 대한 항목이있는 경우, 우리는 추가하거나 p[v[c]]에서 v.totalNumberOfStrikes을 뺍니다. 값이 아직 존재하지 않으면주의해야합니다. 식 || 0은 기본값이 정의되지 않은 경우 값을 0으로 기본값 설정합니다.

다음, 우리는 (값으로 정렬)과 같이 동적으로 스택을 만들 수 있습니다 : 여기

var reducedCountries = strikingCountriesGroup.all()[0].value; 
    var countries = d3.keys(reducedCountries).sort(function(a, b) { 
     return reducedCountries[b] - reducedCountries[a]; 
    }); 

    // we have to special-case the first group, see https://github.com/dc-js/dc.js/issues/797 
    var first = countries.shift(); 
    strikingCountries 
     .group(strikingCountriesGroup, first, 
     function(d) { 
      return d.value[first]; 
     }); 
    // rest 
    countries.forEach(function(c) {  
     strikingCountries 
      .stack(strikingCountriesGroup, c, 
      function(d) { 
       return d.value[c]; 
      }); 
    }); 

바이올린 : http://jsfiddle.net/gordonwoodhull/gfe04je9/11/ 여기

1

아마이 작업을 수행하는 가장 쉬운 방법은 당신이 당신의 소스 Date, Country, Target을 가지고 있으므로, 배열을 평평하게하는 것입니다. (테스트되지 않은) 식으로 뭔가 : 다음

var dest = []; 
var countries = ["Country 1", "Country 2", ...] 
source.forEach(function(d) { 
    countries.forEach(function(c) { 
     dest.push({Date: d.Date, Country: c, Target: d.Target}); 
    }); 
}); 

그리고는 대신 원본 데이터의 crossfilter하는 dest를 전달합니다.

이런 식으로 일을의 장점은 차트의 행을 클릭 지금 때, 개별 국가 차트의 나머지를 필터링 할 수 있다는 것입니다. 교차 필터는 행 단위로만 필터링되기 때문에 실수로 해당 행을 공유하는 다른 국가를 필터링하지 않고 개별 국가별로 필터링하는 다른 방법 (심각한 속임수가 없음)이 없습니다.

+0

만 문제는 사용자의 수와 금액은 어떤에서 팽창 될 예정이다 귀하의 국가 차원 외에도 이 상황을 처리해야하는 경우 해당 문제를 처리하는 사용자 지정 그룹을 정의하는 방법이 있습니다. –

+0

아, 그게 좋은 지적입니다. 각 국가의 밭을 가진 물건으로 축소하려고하십니까? – Gordon

+0

나는 정말 실종됐다.어제부터 어제부터 아무런 문제없이 꾸몄다. ( – basbabybel