2012-07-26 1 views
12

내가 찾은 모든 d3 자습서는 배열의 각 객체에 대해 한 점을 그래프로 표시하는 객체 배열로 배열 된 데이터를 사용합니다. 다음 구조의 데이터를 제공합니다 :d3.js는 동일한 소스의 데이터를 사용하여 동일한 그래프에 두 개의 산점도를 그릴 수 있습니까?

data = [ 
    {id: 1, x: 4, y: 10, type: 1}, 
    {id: 2, x: 5, y: 20, type: 2} 
    ... 
] 
x 및 y 값은 산점도를 만드는 데 사용됩니다. type 매개 변수는 각 점의 색상을 변경하는 데 사용됩니다. 예를 들어,이 jsfiddle을 참조하십시오. http://jsfiddle.net/uxbHv/

유감스럽게도 다른 데이터 구조를 가지고 있으며 각 개체에 대해 두 개의 데이터 요소를 그려 동일한 그래프를 만드는 방법을 알 수 없습니다. 다음은 몇 가지 예를 들어 데이터입니다 : 내가 yVar1 또는 yVar2에 대해 개별적으로 xVar 그래프 수

dataSet = [ 
    {xVar: 5, yVar1: 90, yVar2: 22}, 
    {xVar: 25, yVar1: 30, yVar2: 25}, 
    {xVar: 45, yVar1: 50, yVar2: 80}, 
    {xVar: 65, yVar1: 55, yVar2: 9}, 
    {xVar: 85, yVar1: 25, yVar2: 95} 
] 

,하지만 나는 같은 그래프를 모두 활용하는 방법을 알아낼 수 없습니다 : 각 데이터에 대한 http://jsfiddle.net/634QG/

답변

30

data-join을 사용하는 일반적인 규칙은 데이터에서까지 일대일 매핑을 으로 바꾸는 것입니다. 따라서 산점도에 두 개의 시리즈가있는 경우 시리즈를 나타내는 두 개의 컨테이너 요소 (예 : G elements)가 필요합니다. 현재 data 배열이 하나뿐이므로 데이터 표현을 동일한 표현으로 두 개의 병렬 배열로 변환하려면 array.map을 사용하는 것이 좋습니다. 이렇게하면 각 계열에 대해 코드를 복제 할 필요가 없습니다.

을위한 하나 X -values에 대한 열 및 여러 다른 컬럼과 파일 데이터는 CSV로 표현 된 모두 말해 Y 각 시리즈의 -values ​​:

x,y1,y2 
5,90,22 
25,30,25 
45,50,80 
65,55,9 
85,25,95 

당신이 원하는 경우 코드를 완전히 일반화하려면 먼저 계열 이름 (예 : ["y1", "y2"])을 계산해야합니다. 세 번째 열을 CSV 파일에 추가 한 경우 ["y1", "y2", "y3"] 일 수 있습니다. d3.keys을 사용하여 이름을 계산할 수 있습니다.이 이름은 개체에서 명명 된 속성을 추출합니다. 예를 들어 d3.keys({foo: 1, bar: 2})["foo", "bar"]을 반환합니다.

// Compute the series names ("y1", "y2", etc.) from the loaded CSV. 
var seriesNames = d3.keys(data[0]) 
    .filter(function(d) { return d !== "x"; }) 
    .sort(); 

이제 일련 이름이 생겼으므로 포인트 배열 배열을 만들 수 있습니다. 외부 배열은 계열 (두 개가 있음)을 나타내고 내부 배열은 데이터 요소를 저장합니다. 포인트를 일관된 표현 (xy 속성을 가진 객체)으로 동시에 변환 할 수 있으므로 일련의 코드를 재사용 할 수 있습니다.

// Map the data to an array of arrays of {x, y} tuples. 
var series = seriesNames.map(function(series) { 
    return data.map(function(d) { 
    return {x: +d.x, y: +d[series]}; 
    }); 
}); 

참고이 코드는 + 연산자를 사용하여 CSV 값을 숫자로 강제 변환합니다. CSV 파일은 형식이 지정되지 않으므로 처음에는 문자열입니다.)

데이터를 정규 형식으로 매핑 했으므로 각 계열에 대해 G 요소를 만든 다음 각 점에 대해 요소를 동그라미로 나타낼 수 있습니다. 그 결과 SVG 구조는 다음과 같이 표시됩니다

<g class="series"> 
    <circle class="point" r="4.5" cx="1" cy="2"/> 
    <circle class="point" r="4.5" cx="3" cy="2"/> 
    … 
</g> 
<g class="series"> 
    <circle class="point" r="4.5" cx="5" cy="4"/> 
    <circle class="point" r="4.5" cx="7" cy="6"/> 
    … 
</g> 

그리고 해당 D3 코드 :

// Add the points! 
svg.selectAll(".series") 
    .data(series) 
    .enter().append("g") 
    .attr("class", "series") 
    .style("fill", function(d, i) { return z(i); }) 
    .selectAll(".point") 
    .data(function(d) { return d; }) 
    .enter().append("circle") 
    .attr("class", "point") 
    .attr("r", 4.5) 
    .attr("cx", function(d) { return x(d.x); }) 
    .attr("cy", function(d) { return y(d.y); }); 

나는 또한 채우기 스타일을 추가하여 각 시리즈에 고유 한 색을 지정하는 코드의 비트를 추가 한을 함유 G 원소에 첨가한다. 물론 이렇게하는 데는 여러 가지 방법이 있습니다. (예를 들어, 각 시리즈의 색상에 대한 자세한 내용을 원할 수 있습니다.) xy 개의 축 (축 렌더링은 제외)의 도메인을 계산하는 코드는 생략했습니다. 하지만 당신은 전체 작업 예를보고 싶다면 : 솔루션에 대한

+0

튜토리얼 거의 ... 마이크 보스 토크 (Mike Bostock)와 같은 긴 답변을 통해 답변을 얻은 이와 비슷한 질문은 FAQ에 넣어야합니다. – paxRoman

4

놓고 두 개의 원을 단일 svg:g 요소를 가리 킵니다. 이렇게하면 데이터와 요소가 일대일로 매핑되지만 두 가지 다른 점을 표시 할 수 있습니다.

var nodeEnter = vis1.selectAll("circle") 
     .data(dataSet) 
     .enter() 
     .insert("svg:g"); 

nodeEnter.insert("svg:circle") 
      .attr("cx", function (d) { return 100 - d.xVar}) 
      .attr("cy", function (d) { return 100 - d.yVar1}) 
      .attr("r", 2) 
      .style("fill", "green"); 

nodeEnter.insert("svg:circle") 
      .attr("cx", function (d) { return 100 - d.xVar}) 
      .attr("cy", function (d) { return 100 - d.yVar2}) 
      .attr("r", 2) 
      .style("fill", "blue"); 

JSFiddle 작업.

+0

감사합니다! 나는 이것이 정적 데이터와 어떻게 작동 하는지를 보았으나 이제 전이와 종료를 추가하는 것이 어려울 지 궁금하다 .... 다시 ... jsfiddle ... –

+0

이것은 (지금) 작동 할 수도 있지만, API는 이러한 방식으로 작동하도록 설계되지 않았습니다. 데이터 조인을 사용할 때는 항상 데이터와 요소 사이에 일대일 매핑이 있어야합니다. 입력 선택을 두 번 삽입하거나 추가하는 것은 API의 오용입니다. 이 경우 올바른 해결책은 두 개의 'vis'요소를 만들고 일관된 표현으로 두 개의 병렬 배열에 데이터를 매핑하는 것입니다. – mbostock

+0

@mbostock 더 나은 접근 방법인가요? http://jsfiddle.net/634QG/3/ –

관련 문제