2015-08-28 2 views
0

Я хотел добавить метки данных на каждом поле в барах, но не мог понять, как это сделать. Все примеры, которые я нашел в сети, - это получение данных из простых массивов, а не внешнего файла JSON, как я.Stacked Vertical Bar Chart Labeling - D3.js

Вот мой код:

<!DOCTYPE html> 
<meta charset="utf-8"> 
<style> 

body { 
    font: 10px sans-serif; 
} 

.axis path, 
.axis line { 
    fill: none; 
    stroke: #000; 
    shape-rendering: crispEdges; 
} 

.bar { 
    fill: steelblue; 
} 

.x.axis path { 
    display: none; 
} 

</style> 
<body> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> 
<script> 

var margin = {top: 20, right: 20, bottom: 30, left: 40}, 
    width = 960 - margin.left - margin.right, 
    height = 500 - margin.top - margin.bottom; 

var x = d3.scale.ordinal() 
    .rangeRoundBands([0, width], .1); 

var y = d3.scale.linear() 
    .rangeRound([height, 0]); 

var color = d3.scale.ordinal() 
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]); 

var xAxis = d3.svg.axis() 
    .scale(x) 
    .orient("bottom"); 

var yAxis = d3.svg.axis() 
    //.scale(y) 
    .orient("left") 
    .tickFormat(d3.format(".2s")); 

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

d3.json("data.json", function(error, data) { 
    if (error) throw error; 

    color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Brand"; })); 

    data.forEach(function(d) { 
    var y0 = 0; 
    d.stores = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; }); 
    d.total = d.stores[d.stores.length - 1].y1; 
    }); 

    data.sort(function(a, b) { return b.total - a.total; }); 

    x.domain(data.map(function(d) { return d.Brand; })); 
    y.domain([0, d3.max(data, function(d) { return d.total; })]); 

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

    var brand = svg.selectAll(".brand") 
     .data(data) 
    .enter().append("g") 
     .attr("class", "g") 
     .attr("transform", function(d) { return "translate(" + x(d.Brand) + ",0)"; }); 

    brand.selectAll("rect") 
     .data(function(d) { return d.stores; }) 
    .enter().append("rect") 
     .attr("width", x.rangeBand()) 
     .attr("y", function(d) { return y(d.y1); }) 
     .attr("height", function(d) { return y(d.y0) - y(d.y1); }) 
     .style("fill", function(d) { return color(d.name); }); 

    var legend = svg.selectAll(".legend") 
     .data(color.domain().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; }); 

}); 

</script> 

data.json

[ 
    { 
     "Brand": "A", 
     "LAST 3 MONTHS": "22", 
     "LAST MONTH": "15", 
     "THIS YEAR": "36", 
     "ALL STORES": "72" 
    }, 
    { 
     "Brand": "B", 
     "LAST 3 MONTHS": "10", 
     "LAST MONTH": "24", 
     "THIS YEAR": "15", 
     "ALL STORES": "61" 
    }, 
    { 
     "Brand": "C", 
     "LAST 3 MONTHS": "10", 
     "LAST MONTH": "11", 
     "THIS YEAR": "23", 
     "ALL STORES": "67" 
    }, 
    { 
     "Brand": "D", 
     "LAST 3 MONTHS": "10", 
     "LAST MONTH": "17", 
     "THIS YEAR": "21", 
     "ALL STORES": "81" 
    }, 
    { 
     "Brand": "E", 
     "LAST 3 MONTHS": "10", 
     "LAST MONTH": "31", 
     "THIS YEAR": "51", 
     "ALL STORES": "92" 
    }, 
    { 
     "Brand": "F", 
     "LAST 3 MONTHS": "10", 
     "LAST MONTH": "27", 
     "THIS YEAR": "35", 
     "ALL STORES": "76" 
    }, 
    { 
     "Brand": "G", 
     "LAST 3 MONTHS": "10", 
     "LAST MONTH": "23", 
     "THIS YEAR": "19", 
     "ALL STORES": "59" 
    }, 
    { 
     "Brand": "H", 
     "LAST 3 MONTHS": "32", 
     "LAST MONTH": "27", 
     "THIS YEAR": "15", 
     "ALL STORES": "45" 
    } 
] 

Как я могу показать метки данных на каждой коробки в барах? (Например: 22, 15, 36, 72 на первом баре и т.д.)

Я хочу, чтобы окончательный вид на всех барах, как первый бар на этой картинке: https://dl.dropboxusercontent.com/u/58490833/Yollanan%20Dosyalar/stackedbar.jpg

ответ

0

Do тот же код, как вы делали для всех прямоугольника .. но вы должны либо передать исходный объект с ним, чтобы прочитать значение или вы можете получить его от родительского узла, как этот

brand.selectAll("text") 
    .data(function(d) { return d.stores; }) 
    .enter().append("text") 
    .attr("y", function(d) { return y(d.y1)+10; }) 
    .attr("x", x.rangeBand()/2) 
    .attr("text-anchor","middle") 
    .style("fill",'#fff') 
    .text(function(d) { return d3.select(this)[0][0].parentNode.__data__[d.name]; }); 

здесь является fiddle с раствором надеюсь, что это то, что вам нужно ..

+1

.text (function (d) {return d3.select (это) [0] [0] .parentNode .__ данные __ [d.name]; }); это то, что мне нужно. Спасибо огромное! –

+0

Но пока вы набираете массив для магазинов, вы можете добавить к нему оригинальный объект ... И использовать его здесь –