2015-01-24 3 views
0

Fiddle ExampleX, Y 도메인 데이터 바인딩 d3.js

여러 그룹화 막대 차트는 I는 동일한 페이지에 작은 여러 그룹화 막대 그래프를 작성하기 위해 이들 두 가지 예 (1) (2)을 따르고있다. 여기에 JSON 데이터의 예입니다 : 나는 바의 값이 각 차트에서 올바르게 표시 얻을 관리했습니다

var data = [ 
{"name":"AA","sales_price":20,"retail_price":25}, 
{"name":"BB","sales_price":30,"retail_price":45}, 
{"name":"CC","sales_price":10,"retail_price":55}, 
{"name":"DD","sales_price":10,"retail_price":25}, 
{"name":"EE","sales_price":13,"retail_price":20}, 
{"name":"GG","sales_price":13,"retail_price":15}, 
]; 

하지만 X 도메인과 Y 도메인 값은 잘하지 않습니다. 각 데이터 행의 sales_priceretail_price을 전체 JSON 데이터 대신 축에 바인딩하는 방법을 알 수 없습니다. 이 코드 블록에는 문제가있는 것으로 생각됩니다.

도메인이 각 그룹화 된 막 대형 차트에 대해 각 행의 값을 반환하도록하려면 어떻게해야합니까?

전체 코드 : X0, X1와 y의

function multi_bars(el){ 
var margin = {top: 45, right:20, bottom: 20, left: 50}, 
    width = 350 - margin.left - margin.right, 
    height = 250 - margin.top - margin.bottom; 
var x0 = d3.scale.ordinal() 
    .rangeRoundBands([0, width], .1); 
var x1 = d3.scale.ordinal(); 
var color = d3.scale.ordinal() 
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]); 
var y = d3.scale.linear() 
    .range([height, 0]); 
var xAxis = d3.svg.axis() 
    .scale(x0) 
    .orient("bottom"); 
var yAxis = d3.svg.axis() 
    .scale(y) 
    .orient("left"); 
var field_name = ['retail_price','sales_price']; 
data.forEach(function(d) { 
    d.compare = field_name.map(function(name) {  
     return {name: name, value: +d[name]}; 
    }); 
}); 

x0.domain(data.map(function(d) { console.log(d); return d.name; })); 
x1.domain(field_name).rangeRoundBands([0, x0.rangeBand()]); 
y.domain([0, d3.max(data, function(d) { 
     return d3.max(d.compare, function(d) {   
     return d.value; }); 
})]); 

var svg = d3.select(el).selectAll("svg") 
    .data(data) 
    .enter().append("svg:svg") 
    .attr("width", width + margin.left + margin.right) 
    .attr("height", height + margin.top + margin.bottom) 
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

svg.append("g") 
    .attr("class", "x axis") 
    .attr("transform", "translate(0," + height + ")") 
    .call(xAxis); 

svg.append("g") 
    .attr("class", "y axis") 
    .call(yAxis) 
    .append("text") 
    .attr("transform", "rotate(-90)") 
    .attr("y", 6) 
    .attr("dy", ".71em") 
    .style("text-anchor", "end") 
    .text("Price"); 


    // Accessing nested data: https://groups.google.com/forum/#!topic/d3-js/kummm9mS4EA 
    // data(function(d) {return d.values;}) 
    // this will dereference the values for nested data for each group 
    svg.selectAll(".bar") 
    .data(function(d) {return d.compare;}) 
    .enter() 
    .append("rect") 
    .attr("class", "bar") 
    .attr("x", function(d) { return x1(d.name); }) 
    .attr("width", x1.rangeBand()) 
    .attr("y", function(d) { return y(d.value); }) 
    .attr("height", function(d) { return height - y(d.value); }) 
    .attr("fill", color) 

    var legend = svg.selectAll(".legend") 
     .data(field_name.slice().reverse()) 
    .enter().append("g") 
     .attr("class", "legend") 
     .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }); 

    legend.append("rect") 
     .attr("x", width - 18) 
     .attr("width", 18) 
     .attr("height", 18) 
     .style("fill", color); 

    legend.append("text") 
     .attr("x", width - 24) 
     .attr("y", 9) 
     .attr("dy", ".35em") 
     .style("text-anchor", "end") 
     .text(function(d) { return d; }); 

function type(d) { 
    d.percent = +d.percent; 
    return d; 
} 

} 

multi_bars(".container"); 

답변

3

귀하의 설정까지 괜찮습니다.

나중에 DOM을 조작하면 데이터에 대한 참조가 작동하지 않습니다. 은 내가 두 가지 일을했을 : 우선 첫 번째 블록을 변경, 대신

var svg = d3.select(el).selectAll("svg") 
.data(data) 
.enter().append("svg:svg") 
.attr("width", width + margin.left + margin.right) 
.attr("height", height + margin.top + margin.bottom) 
.append("g") 
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

의 한 SVG를 만들 수 있도록 나중에 그냥 http://bl.ocks.org/mbostock/3887051의 예를 따라하고 그에 따라 변경했습니다. 결과는 여기에 있습니다 : http://jsfiddle.net/ee2todev/g61f93gx/

당신은 당신은 단지 X0 규모와 각 막대를 번역해야 원래 바이올린의 각 그룹에 대한 별도의 차트를 원한다면 . 그냥이 조정 만들 수 있습니다

는 바 선택

data.forEach(function(d) { 
d.compare = field_name.map(function(name) {  
    return {group: d.name, name: name, value: +d[name]}; 
}); 

})에서 해당 데이터에서 액세스 할 수 있도록이 d.compare에 그룹 이름을 추가 할 필요가); 바 선택에서

b)는 그에 따라 각 그룹을 번역 할 수 있습니다

svg.selectAll(".bar") 
.data(function(d) {return d.compare;}) 
.enter() 
.append("rect") 
.attr("class", "bar") 
.attr("transform", function(d) { return "translate(" + x0(d.group) + ",0)"; }) 
.attr("x", function(d) { console.log("x: "+d.value); return x1(d.name); }) 
.attr("width", x1.rangeBand()) 
.attr("y", function(d) { return y(d.value); }) 
.attr("height", function(d) { return height - y(d.value); }) 
.attr("fill", color); 

전체 바이올린은 여기에 있습니다 : http://jsfiddle.net/ee2todev/en8sr5m4/

두 가지 이상의 음 : 1) 난 그냥 약간의 코드를 변경했습니다. 의미 있고 직관적 인 변수/객체 이름을 사용하는 것이 좋습니다. 이것은 나에게 오류를 최소화하는 가장 효과적인 방법입니다. 이것은 당신이 혼란 스러웠던 이유 였을 것입니다. 그래서 d.compare 속성의 이름을 변경합니다 (예 : {그룹 이름 : d.name, 가격 유형 : 이름, 값 : + d [이름]}. 현재 이름에서 원래 데이터와 같이 그룹 이름이 아닌 가격 유형을 갑자기 참조하기 때문에 이름의 의미를 전환했습니다.

2) 선택 항목을 선택하는 좋은 예입니다. 참고 항목 : http://bost.ocks.org/mike/nest/ 첫 번째 selectAll 선택 (svg 변수)에는 객체가 포함 된 Array [6]가 있습니다.두 번째 선택 : 가격 유형 및 값을 갖는 객체를 포함하는 배열 [2]를 통해 SVG 데이터의 각 요소에 대한

svg.selectAll(".bar").data(function(d) {return d.compare;}) 

반복. 나는 그룹 이름을 추가했다.

+0

도움 주셔서 감사합니다. 하나. [툴팁을 포함한 작은 다중 막대 차트] (http://bl.ocks.org/officeofjane/7315455)의 예제는 실제로 내가 달성하고자하는 것입니다. 동일한 페이지에서 별도의 차트를 만들고 싶습니다. 각 JSON 행은 하나의 막 대형 차트입니다. 페이지에 하나의 큰 단일 차트 대신. – RedGiant

+0

오, 죄송합니다. 내가 참조. 두 개의 막대 만 포함 된 차트를 원하십니까? 모든 이름에 대해 x 축을 유지 하시겠습니까? – ee2Dev

+0

즉 바가 x 축을 따라 올바른 위치로 이동하면 결과가 피들을 변경해야한다는 것을 의미합니다. 나머지는 괜찮습니다. – ee2Dev